Typescript 高级类型推断

在普通场景下,使用typescript的基本类型以及高级类型(联合类型,交叉类型等)已经足够,在特殊场景下我们需要对类型进行推断,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映射推断

由对象的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,通常用于由具体值类型推断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

关键字infer 推断

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'>

你可能感兴趣的:(typescript,typescript,javascript)