在普通场景下,使用typescript的基本类型以及高级类型(联合类型,交叉类型等)已经足够,在特殊场景下我们需要对类型进行推断,typescript内置了一部分常用的类型工具
使用typescript类型推断可以帮助我们由一个类型得到另外一个类型
以下为部分内置工具类型以及相关的应用
type Pick = {
[P in K]: T[P];
};
type Readonly = {
readonly [P in keyof T]: T[P];
};
// 将所有属性设为可选
type Partial = {
[P in keyof T]?: T[P];
};
// 将所有属性设为必须
type Required = {
[P in keyof T]-?: T[P];
};
// 例如以此为工具将类型部分属性设置为必需属性
type RequiredProps = {
[p in K]-?: T[p]
} & T
type data = {
a: string
c?: string
d?: boolean
}
// {
// a: string
// c: string
// d ?: boolean
// }
type c = RequiredProps
// Omit 为Pick和Exclude的衍生工具
type Omit = Pick>;
// false
type stringIsNeverSub = string extends never ? true : false
// true, never是所有类型的子类型
type neverExtendString = never extends string ? true : false
type neverExtendUnkonw = never extends unknown ? true : false
type neverExtendAny = never extends any ? true : false
通过三元运算符判断类型是否为某个类型的子类型来进行推断
// 部分
type Falsy = false | null | undefined | 0 | ''
type ToBoolean = T extends Falsy ? false : true
type falseVal = ToBoolean<0> // false
type trueVal = ToBoolean<{}> // true
当然这个是可以多层嵌套的
type Opration = T extends 'add' ? 'addResultType' : T extends 'remove' ? boolean : never
由对象的key 推断类型
type Any = {
foo: 'foo'
bar: {
ant: 'ant'
}
}
// 'foo'
Any['foo']
// 'ant'
Any['bar']['ant']
type Valueof = T[K]
type Values = Valueof
type SomeObj= {
a: '1'
b: 'b',
c: 3
}
Valueof // '1' | 3
Values // '1' | 'b' | 3
const enum OprationTypes {
remove,
add
}
// 推断枚举类型
Valueof // OprationTypes.remove
亦或者这样推断
type InferValue = K extends keyof T ? T[K] : never
特殊的映射推断
type Tuples = Array
// string
Tuples[number]
Tuples[0]
由具体值映射key,通常用于由具体值类型推断key类型,比如枚举
type MapKey>
= { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
当然也可以不限定值的类型,通过值类型获取key类型
type PickProp = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
interface Some {
foo: string
ant: string
bar: 1
play: () => void
}
type stringProp = PickProp // -> 'foo' | 'ant'
type BarProp = PickProp // -> 'bar'
type FnProps = PickProp // -> 'play'
type ActionsKey = PickProp
type PromiseValue> = T extends Promise ? K : never
PromiseValue> // string
// ts内置的类型工具使用infer
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
type Parameters any> = T extends (...args: infer P) => any ? P : never;
该部分会不定期更新
通过三元/infer/递归等组合方式对进行复杂推断
type DeepStringify> = {
[k in keyof T]: T[k] extends Record ? DeepStringify : string
}
// {a: string, b: {foo: string}}
type str = DeepStringify<{ a: number, b: { foo: number } }>
/**
* 获取必须字段的key
* @example
* // 'a' | 'c'
* RequiredPropKey<{a: number, b?: any, c: any}>
* // never
* RequiredPropKey<{a?: number, b?: any}>
*/
export type RequiredPropKey = NonNullable<
{
[k in keyof T]: undefined extends T[k] ? never : { key: k }
}[keyof T]
>['key']
// 通过点号获取属性的值
type LodashPropType = string extends Path
? never
: Path extends keyof T
? T[Path]
: Path extends `${infer K}.${infer R}`
? K extends keyof T
? LodashPropType
: never
: never
// '3'
type bVal = LodashPropType<{a: {b: '3'}}, 'a.b'>