跳到主要内容

高级写法

// 场景:后端接口具有不同参数

interface API {
'/book/detail':{
id:number
},
'/book/comment':{
id:number
comment:string
}
}

function request<T extends keyof API>(url: T,obj: API[T]){
return axios.post(url,obj)
}

// 根据url参数自动推导出配置对象类型

extends

extends 不止可以限制类型,也可以当返回结果判断真假

条件类型中作为条件判断

SomeType extends OtherType ? TrueType : FalseType;

如何得到一个数组类型各个索引的类型?

即判断 a[]这个类型的 a 到底是啥

type Flatten<T>


// awnser
要么一个一个试
T extends string[] ? string : never;

// OR
要么通过infer直接取出
T非数组类型则直接返回T
type Flatten<T> = T extends (infer I)[] ? I : T;

通过infer I 可以取到string[]中的string
type StringArr = string[]

Flatten<StringArr> === "string"


推断多个调用签名的类型(例如重载函数的类型),将从最后一个签名开始进行推断

declare function stringOrNum(x: number): string;
declare function stringOrNum(x: string | number): string | number;
declare function stringOrNum(x: string): number;

type T1 = ReturnType<typeof stringOrNum>;
// type T1 = number

泛型在条件语句中会被分配

比如说参数是<a|b>,则本质是<a>|<b>


type ToArray<Type> = Type extends any ? Type[] : never;

type StrArrOrNumArr = ToArray<string | number>;
// type StrArrOrNumArr === string[] | number[]


可以关闭这一特性
如果不想使用这一特性,可以用方括号将extends两边的变量都包裹起来
type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never;

// 'StrOrNumArr' is no longer a union.
type StrOrNumArr = ToArrayNonDist<string | number>;


这样数组中各项可以是两种类型
// type StrOrNumArr = (string | number)[]

in

const a = {b:true,c:false}

type TurnToBoolean<T> = {
[P in keyof T]: boolean
}


TurnToBoolean<typeof a>

type getModule = {
getCount: () => number;
getMessage: () => string;
}

type TurnGet<T> = {
// 在T类型中,任何以getXxx为键名的键,都会为其统一为()=>该键类型
[Property in keyof T as `get${Capitalize<string & Property>}`]: () => T[Property]
}


getModule: TurnGet<getModule>


例如
TurnGet<{
getXXX: number,
getYYY: boolean,
notTurn: boolean
}>

= {
getXXX: ()=>number,
getYYY: ()=>boolean,
notTurn: boolean
}

浅 Partial

  • 常用的工具泛型 Partial。 功能是将类型的属性变成可选, 注意这是浅 Partial。 type Partial<T = { [P in keyof T]?: T[P] }

深 Partial

如果需要深 Partial 我们可以通过泛型递归来实现

type DeepPartial<T> = T extends Function
? T
: T extends object
? { [P in keyof T]?: DeepPartial<T[P]> }
: T
type PartialedWindow = DeepPartial<Window>

引用

https://zhuanlan.zhihu.com/p/82459341 https://zhuanlan.zhihu.com/p/503812618 https://jkchao.github.io/typescript-book-chinese/tips/infer.html#%E4%B8%80%E4%BA%9B%E7%94%A8%E4%BE%8B https://github.com/piotrwitek/utility-types https://juejin.cn/post/6994102811218673700