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 symbols
是 symbols
的子类型,仅可通过调用 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();
}