TypeSciprt 提供了几种实用类型,方便常见的类型转换。这些类型在全局可用。
原文链接:https://www.typescriptlang.org/docs/handbook/utility-types.html
Awaited<Type> 模拟 async function
中的 await
或 Promises
的 .then()
方法等操作,确切来说,就是递归展开Promises
。
1 2 3 4 5 6 7 8 9 10 11 12 13 type A = Awaited <Promise <string >> type B = Awaited <Promise <Promise <number >>> type C = Awaited <boolean | Promise <number >> function fn1 ( ): Promise <string > { return new Promise (resolve => { resolve ('success' ) }) } type D = Awaited <typeof fn1>
Partial<Type> 构造一个将给定类型Type
的所有属性设置为可选的类型,该实用类型返回给定类型的所有子集的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface Todo { title : string ; description : string ; } function updateTodo (todo: Todo, fieldsToUpdate: Partial<Todo> ) { return { ...todo, ...fieldsToUpdate }; } const todo1 = { title : "organize desk" , description : "clear clutter" , }; const todo2 = updateTodo (todo1, { description : "throw out trash" , });
Required<Type> 构造一个将给定类型Type
的所有属性设置为必需的类型,和Partial
相反。
1 2 3 4 5 6 7 8 9 interface Props { a?: number ; b?: string ; } const obj : Props = { a : 5 }; const obj2 : Required <Props > = { a : 5 };
Readonly<Type> 构造一个将给定类型Type
的所有属性设置为只读的类型。将不能重新给所构造类型的属性分配值。
1 2 3 4 5 6 7 8 9 10 interface Todo { title : string ; } const todo : Readonly <Todo > = { title : "Delete inactive users" , }; todo.title = "Hello" ;
Record<Keys, Type> 构造一个对象类型,其键的属性为Keys
,值的属性为Type
。这个工具类型可以用于将一个类型的属性映射到另一个类型。
1 2 3 4 5 6 7 8 9 10 11 12 interface CatInfo { age : number ; breed : string ; } type CatName = "miffy" | "boris" | "mordred" ; const cats : Record <CatName , CatInfo > = { miffy : { age : 10 , breed : "Persian" }, boris : { age : 5 , breed : "Maine Coon" }, mordred : { age : 16 , breed : "British Shorthair" }, };
Pick<Type, Keys> 通过从给定的类型Type
中选择一组属性Keys
(字符串字面量或字符串字面量的联合)构建一个类型。
1 2 3 4 5 6 7 8 9 10 11 12 interface Todo { title : string ; description : string ; completed : boolean ; } type TodoPreview = Pick <Todo , "title" | "completed" >; const todo : TodoPreview = { title : "Clean room" , completed : false , };
Omit<Type, Keys> 通过从给定类型Tpye
中移除Keys
(字符串字面量或字符串字面量的联合)构造一个类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 interface Todo { title : string ; description : string ; completed : boolean ; createdAt : number ; } type TodoPreview = Omit <Todo , 'description' >;const todo : TodoPreview = { title : 'Clean room' , completed : false , createdAt : 1615544252770 } type TodoInfo = Omit <Todo , 'completed' | 'createdAt' >;const todoInfo : TodoInfo = { title : 'Pick up kids' , description : 'Kindergarten closes at 5pm' }
Exclude<UnionType, ExcludedMembers> 通过从UnionType
中排除可分配给ExcludedMembers
的所有联合成员构造一个类型。
1 2 3 4 5 6 7 8 type T0 = Exclude <'a' | 'b' | 'c' , 'a' >;type T1 = Exclude <'a' | 'b' | 'c' , 'a' | 'b' >;type T2 = Exclude <string | number | (() => void ), Function >;
通过从给定类型Type
中提取可分配给Union
的所有联合成员来构造一个类型。
1 2 3 4 5 type T0 = Extract <'a' | 'b' | 'c' , 'a' | 'f' >;type T1 = Extract <string | number | (() => void ), Function >;
NonNullable<Type> 通过从给定类型Type
中排除null
和undefined`来构造一个类型。
1 2 3 4 5 type T0 = NonNullable <string | number | undefined >;type T1 = NonNullable <string [] | null | undefined >;
Parameters<Type> 从给定的函数类型Type
的形参中使用的类型构造一个元组类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function f1 (arg: { a: number ; b: string } ) {}type T0 = Parameters <() => string >;type T1 = Parameters <(s: string ) => void >;type T2 = Parameters <<T>(arg: T ) => T>;type T3 = Parameters <typeof f1>;type T4 = Parameters <any >;type T5 = Parameters <never >;type T6 = Parameters <string >;type T7 = Parameters <Function >;
ConstructorParameters<Type> 用给定的构造函数的类型Type
构造元组或数组。生成一个具有所有形参类型的元组类型(如果Type
不是函数,该类型为never
)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 type T0 = ConstructorParameters <ErrorConstructor >type T1 = ConstructorParameters <FunctionConstructor >type T2 = ConstructorParameters <RegExpConstructor >type T3 = ConstructorParameters <any >type T4 = ConstructorParameters <Function >
ReturnType<Type> 构造一个由给定函数类型Type
的返回类型组成的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const f1 = ( ) => ({ a : 1 , b : '' })type T0 = ReturnType <() => string >;type T1 = ReturnType <(s: string ) => void >;type T2 = ReturnType <<T>() => T>;type T3 = ReturnType <<T extends U, U extends number []>() => T>;type T4 = ReturnType <typeof f1>;type T5 = ReturnType <any >;type T6 = ReturnType <never >;type T7 = ReturnType <string >;type T8 = ReturnType <Function >;
InstanceType<Type> 构造一个类型,由Type
中构造函数实力类型组成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class C { x = 0 y = 0 } type T0 = InstanceType <typeof C>;type T1 = InstanceType <any >;type T2 = InstanceType <never >;type T3 = InstanceType <string >;type T4 = InstanceType <Function >;
ThisParameterType<Type> 提取函数类型Type
的this形参
的类型,如果Type
没有此形参,则为unknown
1 2 3 4 5 6 7 function toHex (this : number ) { return this .toString () } function numberToString (n: ThisParameterType<typeof toHex> ) { return toHex.apply (n) }
OmitThisParameter<Type> 从函数类型Type
中移除this形参
。如果Type
没有显式声明this
形参,结果就是Type
。否则,将依照Type
创建一个不带此形参的新函数。泛型被删除,只有最后一个重载签名被传到新的函数类型中。
1 2 3 4 5 6 7 function toHex (this : number ) { return this .toString (16 ) } const fiveToHex : OmitThisParameter <typeof toHex> = toHex.bind (5 )console .log (fiveToHex ())
ThisType<Type> 该实用类型不返回转换后的类型。它是上下文this
类型的标记。要使用这个实用类型,必须启用noImplicitThis
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 type ObjectDescriptor <D, M> = { data?: D; methods?: M & ThisType <D & M>; }; function makeObject<D, M>(desc : ObjectDescriptor <D, M>): D & M { const data : object = desc.data || {} const methods : object = desc.methods || {} return { ...data, ...methods } as D & M } const obj = makeObject ({ data : { x : 0 , y : 0 }, methods : { moveBy (dx: number , dy: number ) { this .x += dx this .y += dy } } }) obj.x = 10 obj.y = 20 obj.moveBy (5 , 5 )
Uppercase<StringType> 将字符串中的每个字符串转换为大写。
1 2 3 4 5 6 7 8 9 type Greeting = 'Hello World' type ShoutyGreeting = Uppercase <Greeting >type ASCIICacheKey <Str extends string > = `ID-${Uppercase<Str>} ` type MainID = ASCIICacheKey <'my_app' >
Lowercase<StringType>
将字符串中的每个字符串转换为小写。
1 2 3 4 5 6 7 8 9 type Greeting = 'Hello World' type ShoutyGreeting = Lowercase <Greeting >type ASCIICacheKey <Str extends string > = `ID-${Lowercase<Str>} ` type MainID = ASCIICacheKey <'my_app' >
Capitalize<StringType> 将字符串的第一个字符转为大写。
1 2 3 4 type LowercaseGreeting = "hello, world" ;type Greeting = Capitalize <LowercaseGreeting >;
Uncapitalize<StringType> 将字符串的第一个字符转为小写。
1 2 3 4 type UppercaseGreeting = "HELLO WORLD" ;type UncomfortableGreeting = Uncapitalize <UppercaseGreeting >;