版本更新日志
从TypeScript
官方版本日志中列举一些日常工作中可能会高频使用的功能。
4.5
Awaited
type p1 = Promise<number>
type A1 = Awaited<p1> // number;
type A2 = Awaited<string | Promise<number>> // string | number
top-level await
module: es2022
支持top-level await
(此时target
需要大于等于es2017
)
const value = await Promise.resolve(233)
export {}
type modifier
import { age } from './test'
import type { People } from './test' // 老写法
let p: People;
import { age, type People } from './test' // 新写法
4.4
增强控制流分析
function fn(value: unknown) {
const flag = typeof value === 'number';
if (flag) {
value.toFixed()
}
}
function doSomeChecks(
inputA: string | undefined,
inputB: string | undefined,
shouldDoExtraWork: boolean
) {
const mustDoWork = inputA && inputB && shouldDoExtraWork;
if (mustDoWork) {
// We can access 'string' properties on both 'inputA' and 'inputB'!
const upperA = inputA.toUpperCase();
const upperB = inputB.toUpperCase();
// ...
}
}
索引类型支持Symbol、模板字符串
interface T {
[name: symbol]: string;
[data: `data-${string}`]: string;
}
4.3
Contextual Narrowing for Generics
极大改善了范型参数的narrow
,详情见链接,避免了如下这种常见的错误提示。
declare function takeA(a: 'a'): void;
function f2<T extends 'a' | 'b'>(x: T) {
if (x === 'a') {
// Argument of type 'T' is not assignable to parameter of type '"a"'.
// Type '"a" | "b"' is not assignable to type '"a"'.
// Type '"b"' is not assignable to type '"a"'.(2345)
takeA(x); // 4.2版本及以前都会报错
}
}
4.2
元祖支持前置、中置 rest 元素
type tuple = [number, ...string[], number];
function fn(...args: [...string[], number]) {
}
fn('a', 'b', 'c', 3)
4.1
新增模板字面量类型
映射类型(Mapped types)支持 as 子句
通过支持as
子句实现键值的重新映射,语法如下,能够把P
重新映射为N
。
type A = {
[P in K as N]: X
}
例子一:🌰
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};
interface Person {
name: string;
age: number;
location: string;
}
type LazyPerson = Getters<Person>;
需要注意的是如同我们在映射类型一节所提到的,[K in T]
中的T
需要满足是string | number | symbol
的子类型,同时我们在这个例子中并没有约束T
的类型,所以在使用Captialize
的时候我们需要使用string & K
来排除K
可能的number | symbol
类型。
例子二:🌰
When the type specified in an
as
clause resolves tonever
, no property is generated for that key。
当as
子句中指定的类型被解析成never
,那么对于这个键没有对应的属性生成,所以as
子句可以用来做过滤器。
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
type T60 = Methods<{ foo(): number, bar: boolean }>; // { foo(): number }
例子三:🌰
When the type specified in an
as
clause resolves to a union of literal types, multiple properties with the same type are generated
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
type T70 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
4.0
Variadic Tuple Types
function tail<T extends any[]>(arr: readonly [any, ...T]) {
const [_ignored, ...rest] = arr;
return rest;
}
type Arr = readonly any[];
function concat<T extends Arr, U extends Arr>(arr1: T, arr2: U): [...T, ...U] {
return [...arr1, ...arr2];
}
// spreads
type Strings = [string, string];
type Numbers = [number, number];
type StrStrNumNumBool = [...Strings, ...Numbers, boolean];