TypeScript / 前端 · 10月 7, 2020 0

TypeScript学习笔记2-更新日志

2.8版本

2.8.1 有条件类型

TypeScript 2.8 引入了有条件类型,它能够表示非统一的类型。 有条件的类型会以一个条件表达式进行类型关系检测,从而在两种类型中选择其一:

T extends U ? X : Y

意思是,若 T 能够赋值给 U ,那么类型是 X ,否则为 Y 。

类似于三元表达式:

type TypeName<T> =
    T extends string ? "string" :
    T extends number ? "number" :
    T extends boolean ? "boolean" :
    T extends undefined ? "undefined" :
    T extends Function ? "function" :
    "object";

type T0 = TypeName<string>;  // "string"
type T1 = TypeName<"a">;  // "string"
type T2 = TypeName<true>;  // "boolean"
type T3 = TypeName<() => void>;  // "function"
type T4 = TypeName<string[]>;  // "object"

2.8.2 有条件类型中的类型推断

现在在有条件类型的extends子语句中,允许出现infer声明,它会引入一个待推断的类型变量。 这个推断的类型变量可以在有条件类型的true分支中被引用。

例如,下面代码会提取函数类型的返回值类型:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

在协变位置上,同一个类型变量的多个候选类型会被推断为联合类型;

type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
type T10 = Foo<{ a: string, b: string }>;  // string
type T11 = Foo<{ a: string, b: number }>;  // string | number

在抗变位置上,同一个类型变量的多个候选类型会被推断为交叉类型:

type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
type T20 = Bar<{ a: (x: string) => void, b: (x: string) => void }>;  // string
type T21 = Bar<{ a: (x: string) => void, b: (x: number) => void }>;  // string & number

2.8.3 改进对映射类型修饰符的控制

TypeScript 2.8 为映射类型增加了增加或移除特定修饰符的能力。 特别地,映射类型里的 readonly 或 ? 属性修饰符现在可以使用 + 或 – 前缀,来表示修饰符是添加还是移除。

type MutableRequired<T> = { -readonly [P in keyof T]-?: T[P] };  // 移除readonly和?
type ReadonlyPartial<T> = { +readonly [P in keyof T]+?: T[P] };  // 添加readonly和?

2.7版本

2.7.1 显式赋值断言

显式赋值断言是一个新语法,使用它来告诉 TypeScript 一个属性会被明确地赋值。 但是除了在类属性上使用它之外,在 TypeScript 2.7 里你还可以在变量声明上使用它!

let x!: number[];//显式赋值断言 '!'
initialize();
x.push(4);

function initialize() {
    x = [0, 1, 2, 3];
}

2.7.2 unique symbol 类型和常量名属性

unique symbolssymbols 的子类型,仅可通过调用 Symbol()Symbol.for() 或由明确的类型注释生成。 它们仅出现在常量声明和只读的静态属性上,并且为了引用一个存在的 unique symbols 类型,你必须使用 typeof 操作符。 每个对 unique symbols 的引用都意味着一个完全唯一的声明身份。

// work
declare const Foo: unique symbol;

// Error! 'Bar' isn't a constant.
let Bar: unique symbol = Symbol();

// Works - refers to a unique symbol, but its identity is tied to 'Foo'.
let Baz: typeof Foo = Foo;

// Also works.
class C {
    static readonly StaticSymbol: unique symbol = Symbol();
}
冀ICP备19028007号