| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Thanks for the PR! This section of the codebase is owned by Kibeom Kwon (@bumkeyy), YeonJuan (@yeonjuan), Dan Jeong (@guyeol), and Seohee Park (@dvlprsh) - if they write a comment saying "LGTM" then it will be merged. |
Sorry, something went wrong.
|
Translation of TypeScript 4.9.md
title: TypeScript 4.9 oneline: TypeScript 4.9 Release Notessatisfies operatorTypeScript developers often face a dilemma. We have some expressions with this type and _accord_I'd like to make sure it does, but for inference, the expression of _The most specific type_There are times when you want to keep it. For example // 각 속성은 문자열 또는 RGB 튜플일 수 있습니다.
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255]
// ^^^^ sacrebleu - 오타를 냈습니다!
};
// 우리는 배열 메서드를 'red'에 사용하고 싶습니다...
const redComponent = palette.red.at(0);
// 혹은 'green'에 문자열 메서드를 사용하고 싶을 수 있습니다...
const greenNormalized = palette.green.toUpperCase();We are bleu minister blueshould have been written. type Colors = "red" | "green" | "blue";
type RGB = [red: number, green: number, blue: number];
const palette: Record<Colors, string | RGB> = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255]
// ~~~~ 이제 오타를 올바르게 감지했습니다.
};
// 하지만 여기서 원치 않는 문제가 발생했습니다. 'palette.red'가 문자열이 "될 수 있다"는것 입니다.
const redComponent = palette.red.at(0);satisfies You can use operators to verify that the type of an expression matches a specific type without changing the result type of the expression. type Colors = "red" | "green" | "blue";
type RGB = [red: number, green: number, blue: number];
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255]
// ~~~~ 오타가 잡혔습니다!
} satisfies Record<Colors, string | RGB>;
// 두 메서드 모두 여전히 접근할 수 있습니다!
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();satisfiescan be used to detect many errors. type Colors = "red" | "green" | "blue";
// 'Colors' 키가 정확한지 확인합니다.
const favoriteColors = {
"red": "yes",
"green": false,
"blue": "kinda",
"platypus": false
// ~~~~~~~~~~ 에러 - "platypus"는 'Colors' 리스트에 없습니다.
} satisfies Record<Colors, unknown>;
// 'red', 'green' 및 'blue' 속성의 모든 정보가 유지됩니다.
const g: boolean = favoriteColors.green;Sometimes we may be more interested in the type of each attribute than in whether the attribute name matches. type RGB = [red: number, green: number, blue: number];
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0]
// ~~~~~~ 에러!
} satisfies Record<string, string | RGB>;
// 각 속성에 대한 정보는 계속 유지됩니다.
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();For more examples, Proposed issue and A pull request that implements thisCheck it out. Unlisted Property Narrowing with the in OperatorAs developers, we often need to deal with values that aren't fully known at runtime. Previously, TypeScript allowed us to narrow away any types that don't explicitly list a property. interface RGB {
red: number;
green: number;
blue: number;
}
interface HSV {
hue: number;
saturation: number;
value: number;
}
function setColor(color: RGB | HSV) {
if ("hue" in color) {
// 'color' now has the type HSV
}
// ...
}Here, the type RGB didn't list the hue and got narrowed away, and leaving us with the type HSV. But what about examples where no type listed a given property? function tryGetPackageName(context) {
const packageJSON = context.packageJSON;
// Check to see if we have an object.
if (packageJSON && typeof packageJSON === "object") {
// Check to see if it has a string name property.
if ("name" in packageJSON && typeof packageJSON.name === "string") {
return packageJSON.name;
}
}
return undefined;
}Rewriting this to canonical TypeScript would just be a matter of defining and using a type for context; interface Context {
packageJSON: unknown;
}
function tryGetPackageName(context: Context) {
const packageJSON = context.packageJSON;
// Check to see if we have an object.
if (packageJSON && typeof packageJSON === "object") {
// Check to see if it has a string name property.
if ("name" in packageJSON && typeof packageJSON.name === "string") {
// ~~~~
// error! Property 'name' does not exist on type 'object.
return packageJSON.name;
// ~~~~
// error! Property 'name' does not exist on type 'object.
}
}
return undefined;
}This is because while the type of packageJSON was narrowed from unknown to object, the in operator strictly narrowed to types that actually defined the property being checked. TypeScript 4.9 makes the in operator a little bit more powerful when narrowing types that don't list the property at all. So in our example, packageJSON will have its type narrowed from unknown to object to object & Record<"name", unknown> interface Context {
packageJSON: unknown;
}
function tryGetPackageName(context: Context): string | undefined {
const packageJSON = context.packageJSON;
// Check to see if we have an object.
if (packageJSON && typeof packageJSON === "object") {
// Check to see if it has a string name property.
if ("name" in packageJSON && typeof packageJSON.name === "string") {
// Just works!
return packageJSON.name;
}
}
return undefined;
}TypeScript 4.9 also tightens up a few checks around how in is used, ensuring that the left side is assignable to the type string | number | symbol, and the right side is assignable to object. For more information, read the implementing pull request Auto-Accessors in ClassesTypeScript 4.9 supports an upcoming feature in ECMAScript called auto-accessors. class Person {
accessor name: string;
constructor(name: string) {
this.name = name;
}
}Under the covers, these auto-accessors "de-sugar" to a get and set accessor with an unreachable private property. class Person {
#__name: string;
get name() {
return this.#__name;
}
set name(value: string) {
this.#__name = name;
}
constructor(name: string) {
this.name = name;
}
}You can [read up more about the auto-accessors pull request on the original PR](https://github.com/microsoft/TypeScript/pull/49705). NaN Equivalence checkThe main problem for JavaScript developers is that they use the built-in equivalent operators. NaN This is the point to check the value. NaNis a special numeric value, which means "Not a Number". console.log(NaN == 0) // false
console.log(NaN === 0) // false
console.log(NaN == NaN) // false
console.log(NaN === NaN) // falseBut at least symmetrically Everything is always NaNis not the same as console.log(NaN != 0) // true
console.log(NaN !== 0) // true
console.log(NaN != NaN) // true
console.log(NaN !== NaN) // trueAll languages, including IEEE-754 floats, behave the same, so it's technically not just JavaScript. TypeScript is now NaN Comparing the values directly shows an error and Number.isNaN I suggest using it. function validate(someValue: number) {
return someValue !== NaN;
// ~~~~~~~~~~~~~~~~~
// error: This condition will always return 'true'.
// Did you mean '!Number.isNaN(someValue)'?
}We believe this change will go a long way toward catching newbie errors, similar to how TypeScript currently throws errors in comparisons against object and array literals. [contributed to this feature] (https://github.com/microsoft/TypeScript/pull/50626) [Oleksandr Tarasiuk] I would like to thank (https://github.com/a-tarasyuk). Watching Files Using File System EventsIn previous versions, TypeScript used to spy on individual files. _polling_Heavily relied on. In general, a better approach is to use file system events. As a result, we chose the lowest common denominator of polling as the base value. Over time, we have provided the means to [choose a different file surveillance strategy](https://www.typescriptlang.org/docs/handbook/configuring-watch.html). In TypeScript 4.9, file watches are driven by file system events by default and only fall back to polling if you fail to set up an event-driven watcher. [The way file watches work is still based on environment variables and watchOptionscan be configured via [https://www.typescriptlang.org/docs/handbook/configuring-watch.html], and some editors, such as VS Code, watchOptionscan be supported independently.] (https://code.visualstudio.com/docs/getstarted/settings#:~:text=typescript%2etsserver%2ewatchOptions) You can learn more about this change (https://github.com/microsoft/TypeScript/pull/50366) on GitHub. "Remove Unused Imports" and "Sort Imports" Commands for EditorsPreviously, TypeScript only supported two editor commands to manage imports. import { Zebra, Moose, HoneyBadger } from "./zoo";
import { foo, bar } from "./helper";
let x: Moose | HoneyBadger = foo();The first was called "Organize Imports" which would remove unused imports, and then sort the remaining ones. import { foo } from "./helper";
import { HoneyBadger, Moose } from "./zoo";
let x: Moose | HoneyBadger = foo();In TypeScript 4.3, we introduced a command called "Sort Imports" which would only sort imports in the file, but not remove them - and would rewrite the file like this. import { bar, foo } from "./helper";
import { HoneyBadger, Moose, Zebra } from "./zoo";
let x: Moose | HoneyBadger = foo();The caveat with "Sort Imports" was that in Visual Studio Code, this feature was only available as an on-save command - not as a manually triggerable command. TypeScript 4.9 adds the other half, and now provides "Remove Unused Imports". import { Moose, HoneyBadger } from "./zoo";
import { foo } from "./helper";
let x: Moose | HoneyBadger = foo();This feature is available to all editors that wish to use either command; You can [view specifics of the feature here](https://github.com/microsoft/TypeScript/pull/50931). Go-to-Definition on return KeywordsIn the editor, when running a go-to-definition on the return keyword, TypeScript will now jump you to the top of the corresponding function. We expect TypeScript will expand this functionality to more keywords [such as await and yield](https://github.com/microsoft/TypeScript/issues/51223) or [switch, case, and default](https://github.com/microsoft/TypeScript/issues/51225). [This feature was implemented] (https://github.com/microsoft/TypeScript/pull/51227) thanks to [Oleksandr Tarasiuk](https://github.com/a-tarasyuk). Performance improvementsTypeScript has several small but notable performance improvements. First, in all syntax nodes switch Use a function table lookup instead of a statement in TypeScript forEachChild The function has been refactored. forEachChildAfter you see the performance improvements for the NodeT visitEachChildI tried refactoring in . forEachChild's initial exploration was inspired by [blog posts] (https://artemis.sh/2022/08/07/emulating-calculators-fast-in-js.html) by [Artemis Everfree] (https://artemis.sh/). Finally, we've optimized the way TypeScript preserves information about types in the actual branch of conditional types. interface Zoo<T extends Animal> {
// ...
}
type MakeZoo<A> = A extends Animal ? Zoo<A> : never;TypeScript is Zoo<A>When checking if is valid ADegree AnimalYou have to "remember" that it should be. You can learn more about it in each pull request.
Corrections and changeslib.d.ts updateTypeScript tries to avoid major breaks, but even the smallest changes to the built-in libraries can be problematic. Promise.resolve Better types forpresent Promise.resolveto strip away the Promise-like type that is passed by this Awaited Type. JavaScript Export (Emit) no longer omits ImportWhen TypeScript first supported type checking and compilation for JavaScript, it inadvertently supported a feature called import omission. This behavior was particularly troubling given that TypeScript often had to trust inaccurate declaration files when detecting if import was referring to a value. // Input:
import { someValue, SomeClass } from "some-module";
/** @type {SomeClass} */
let val = someValue;
// Previous Output:
import { someValue } from "some-module";
/** @type {SomeClass} */
let val = someValue;
// Current Output:
import { someValue, SomeClass } from "some-module";
/** @type {SomeClass} */
let val = someValue;For more information, see Implementing Change (https://github.com/microsoft/TypeScript/pull/50404). exportsprice typesVersionsIt has a higher priority.Previously, TypeScript --moduleResolution node16 Conditions package.jsonWhen resolving via exports than the field typesVersions Fields took precedence. {
"type": "module",
"main": "./dist/main.js"
"typesVersions": {
"<4.8": { ".": ["4.8-types/main.d.ts"] },
"*": { ".": ["modern-types/main.d.ts"] }
},
"exports": {
".": {
+ "types@<4.8": "4.8-types/main.d.ts",
+ "types": "modern-types/main.d.ts",
"import": "./dist/main.js"
}
}
}For more information, see this pull request(https://github.com/microsoft/TypeScript/pull/50890). SubstitutionTypeIn substituteprice constraintIt is replaced byAs part of the optimization of the substitution type SubstitutionType The object represents an effective substitution (typically an intersection of base type and implicit constraint) substitution It no longer includes the property. minister constraint Include only properties. Read more in the original [pull request] (https://github.com/microsoft/TypeScript/pull/50397). |
Sorry, something went wrong.
|
@microsoft-github-policy-service agree |
Sorry, something went wrong.
There was a problem hiding this comment.
Je-Gwan O (@JeGwan) 고생하셨습니다. 코멘트 남깁니다.
Sorry, something went wrong.
|
YeonJuan (@yeonjuan) Kibeom Kwon (@bumkeyy) |
Sorry, something went wrong.
|
LGTM |
Sorry, something went wrong.
|
Merging because Kibeom Kwon (@bumkeyy) is a code-owner of all the changes - thanks! |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
No description provided.