- Separate Write Types on Properties
- size = 0;
- Template String Type Improvement
- ECMAScript #private Class Elements
ConstructorParametersWorks on Abstract Classes- Contextual Narrowing for Generics
- Always-Truthy Promise Checks
staticIndex Signatures.tsbuildinfoSize Improvements- Lazier Calculations in
--incrementaland--watchCompilations - Import Statement Completions
- Editor Support for
@linkTags - Go-to-Definition on Non-JavaScript File Paths
- Breaking Changes
Separate Write Types on Properties
- 允许
getter的返回类型和setter的参数类型不一致 getter的返回类型G和setter的参数类型S,必须满足G extends S ```typescript // Class class Thing {size = 0;
get size(): number {
return this.#size;
}
set size(value: string | number | boolean) {
let num = Number(value);// Don't allow NaN and stuff.if (!Number.isFinite(num)) {this.#size = 0;return;}this.#size = num;
} }
// Object function makeThing(): Thing { let size = 0; return { get size(): number { return size; }, set size(value: string | number | boolean) { let num = Number(value);
// Don't allow NaN and stuff.if (!Number.isFinite(num)) {size = 0;return;}size = num;}}
}
// Interface // Now valid! interface Thing { get size(): number set size(value: number | string | boolean); }
---<a name="Dkjdx"></a># `override` and `--noImplicitOverride` Flag- `override`关键字:保证父类中必须有同名方法- `--noImplicitOverride` flag:禁用隐式覆盖父类方法,必须使用`override`关键字```typescriptclass SpecializedComponent extends SomeComponent {override show() {// ...}override hide() {// ...}}
Template String Type Improvement
contextually typed:根据上下文类型环境推导类型
function bar(s: string): `hello ${string}` {// Previously an error, now works!return `hello ${s}`;}
更精准的template string类型推导 ```typescript declare let s: string; declare function f
(x: T): T;
// Previously: string
// Now : hello-${string}
let x2 = f(hello ${s});
- 不同template string类型兼容推导更精确```typescriptdeclare let s1: `${number}-${number}-${number}`;declare let s2: `1-2-3`;declare let s3: `${number}-2-3`;declare let s4: `1-${number}-3`;declare let s5: `1-2-${number}`;declare let s6: `${number}-2-${number}`;// Now *all of these* work!s1 = s2;s1 = s3;s1 = s4;s1 = s5;s1 = s6;
ECMAScript #private Class Elements
class Foo {#someMethod() {//...}get #someValue() {return 100;}publicMethod() {// These work.// We can access private-named members inside this class.this.#someMethod();return this.#someValue;}}new Foo().#someMethod();// ~~~~~~~~~~~// error!// Property '#someMethod' is not accessible// outside class 'Foo' because it has a private identifier.new Foo().#someValue;// ~~~~~~~~~~// error!// Property '#someValue' is not accessible// outside class 'Foo' because it has a private identifier
class Foo {static #someMethod() {// ...}}Foo.#someMethod();// ~~~~~~~~~~~// error!// Property '#someMethod' is not accessible// outside class 'Foo' because it has a private identifier.
ConstructorParameters Works on Abstract Classes
abstract class C {constructor(a: string, b: number) {// ...}}// Has the type '[a: string, b: number]'.type CParams = ConstructorParameters<typeof C>;
Contextual Narrowing for Generics
function makeUnique<T, C extends Set<T> | T[]>(collection: C, comparer: (x: T, y: T) => number): C {// Early bail-out if we have a Set.// We assume the elements are already unique.if (collection instanceof Set) {return collection;}// Sort the array, then remove consecutive duplicates.collection.sort(comparer);// ~~~~// error: Property 'sort' does not exist on type 'C'.for (let i = 0; i < collection.length; i++) {// ~~~~~~// error: Property 'length' does not exist on type 'C'.let j = i;while (j < collection.length && comparer(collection[i], collection[j + 1]) === 0) {// ~~~~~~// error: Property 'length' does not exist on type 'C'.// ~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~// error: Element implicitly has an 'any' type because expression of type 'number'// can't be used to index type 'Set<T> | T[]'.j++;}collection.splice(i + 1, j - i);// ~~~~~~// error: Property 'splice' does not exist on type 'C'.}return collection;}
Always-Truthy Promise Checks
async function foo(): Promise<boolean> {return false;}async function bar(): Promise<string> {if (foo()) {// ~~~~~// Error!// This condition will always return true since// this 'Promise<boolean>' appears to always be defined.// Did you forget to use 'await'?return "true";}return "false";}
static Index Signatures
class Foo {static hello = "hello";static world = 1234;static [propName: string]: string | number | undefined;}// Valid.Foo["whatever"] = 42;// Has type 'string | number | undefined'let x = Foo["something"];
.tsbuildinfo Size Improvements
--incremental builds
Lazier Calculations in --incremental and --watchCompilations
Import Statement Completions

Editor Support for @link Tags
/*** To be called 70 to 80 days after {@link plantCarrot}.*/function harvestCarrot(carrot: Carrot) {}/*** Call early in spring for best results. Added in v2.1.0.* @param seed Make sure it's a carrot seed!*/function plantCarrot(seed: Seed) {// TODO: some gardening}
Go-to-Definition on Non-JavaScript File Paths
Breaking Changes
lib.d.ts Changes
删除:
Account, AssertionOptions, RTCStatsEventInit, MSGestureEvent, DeviceLightEvent, MSPointerEvent, ServiceWorkerMessageEvent, WebAuthentication
Errors on Always-Truthy Promise Check
--strictNullChecks
declare var p: Promise<number>;if (p) {// ~// Error!// This condition will always return true since// this 'Promise<number>' appears to always be defined.//// Did you forget to use 'await'?}
Union Enums Cannot Be Compared to Arbitrary Numbers
enum E {A = 0,B = 1,}function doSomething(x: E) {// Error! This condition will always return 'false' since the types 'E' and '-1' have no overlap.if (x === -1) {// ...}}
变通办法:
enum E {A = 0,B = 1,}// Include -1 in the type, if we're really certain that -1 can come through.function doSomething(x: E | -1) {if (x === -1) {// ...}}
enum E {A = 0,B = 1,}// Include -1 in the type, if we're really certain that -1 can come through.function doSomething(x: E | -1) {if (x === -1) {// ...}}
enum E {// the leading + on 0 opts TypeScript out of inferring a union enum.A = +0,B = 1,}
