TypeScript 学习笔记 - infer
先来看一个例子:
type FlattenIfArray<T> = T extends Array<infer R> ? R : T;我们来分析一下以上代码:
首先判断泛型
T是否数组类型;如果是数组类型,将数组成员类型
R抽出来并返回;如果不是数组类型,则原样返回
T;
由于数组类型的定义有两种写法,所以上面的代码还有另外一种写法:
type FlattenIfArray<T> = T extends (infer R)[] ? R : T;再来看一个例子:
type Unpromisify<T> = T extends Promise<infer R> ? R : T;首先判断泛型
T是否 Promise 的子集;如果是,将 Promise 中的泛型
R抽出来并返回;如果不是则原样返回
T;
再来看一个复杂一点的例子:
type FunctionWithOneObjectArgument<P extends { [x: string]: any }, R> = (
props: P,
) => R;
type DestructuredArgsOfFunction<
F extends FunctionWithOneObjectArgument<any, any>
> = F extends FunctionWithOneObjectArgument<infer P, any> ? P : never;
const myFunction = (props: { x: number; y: number }): string => {
return 'ok';
};
const props: DestructuredArgsOfFunction<typeof myFunction> = {
x: 1,
y: 2,
};代码分析:
FunctionWithOneObjectArgument接收两个泛型P和R,然后返回一个函数签名(props: P) => R,而P extends { [x: string]: any }这部分则将参数类型P限定为一个对象。DestructuredArgsOfFunction接收一个泛型F,然后判断F是否FunctionWithOneObjectArgument<P, R>的子集,如果是子集则将其中的P类型抽出来返回,如果不是则返回nevertypeof myFunction会返回myFunction的函数签名,也就是(props: { x: number; y: number }): stringDestructuredArgsOfFunction<typeof myFunction>就相当于DestructuredArgsOfFunction<(props: { x: number; y: number }): string>,我们可以将它代入到DestructuredArgsOfFunction的类型定义中,容易看出infer P会将P推导为{ x: number; y: number },然后我们返回了P,所以props变量的类型就是{ x: number; y: number }了。
Last updated
Was this helpful?