File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -6,7 +6,7 @@ Typescript 官网也拿 `ReturnType` 这一经典例子说明它的作用:
66type ReturnType <T > = T extends (... args : any []) => infer R ? R : any ;
77```
88
9- 理解为:如果 ` T ` 继承了 ` extends (...args: any[]) => any` 类型,则返回类型 ` R ` ,否则返回 ` any ` 。其中 ` R ` 是什么呢?` R ` 被定义在 ` extends (...args: any[]) => infer R ` 中,即 R 是从传入参数类型中推导出来的。
9+ 理解为:如果 ` T ` 继承了 ` (...args: any[]) => any ` 类型,则返回类型 ` R ` ,否则返回 ` any ` 。其中 ` R ` 是什么呢?` R ` 被定义在 ` extends (...args: any[]) => infer R ` 中,即 R 是从传入参数类型中推导出来的。
1010
1111## 精读
1212
@@ -39,7 +39,7 @@ function xxx<T>(value: T): { result: T }
3939而且实际上为了类型安全,我们也不能允许用户描述任意的类型位置,** 万一传入的类型结构不是 ` {label: xxx} ` 而是一个回调 ` () => void ` ,那子类型推导岂不是建立在了错误的环境中。** 所以考虑到想要拿到 ` {label: infer R} ` ,首先参数必须具备 ` {label: xxx} ` 的结构,所以正好可以将 ` infer ` 与条件判断 ` T extends ? A : B ` 结合起来用,即:
4040
4141` ` ` typescript
42- type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never
42+ type GetLabelTypeFromObject<T> = T extends { label: infer R } ? R : never
4343
4444type Result = GetLabelTypeFromObject<{ label: string }>;
4545// type Result = string
@@ -50,7 +50,7 @@ type Result = GetLabelTypeFromObject<{ label: string }>;
5050回过头来看第一个需求,拿到第一个参数类型就可以用 ` infer ` 实现了:
5151
5252` ` ` typescript
53- type GetFirstParamType<T> = T extends ? (...args: infer R) => any ? R[0] : never
53+ type GetFirstParamType<T> = T extends (...args: infer R) => any ? R[0] : never
5454` ` `
5555
5656可以理解为,如果此时 ` T ` 满足 ` (...args: any) => any ` 这个结构,同时我们用 ` infer R ` 表示 ` R ` 这个临时变量指代第一个 ` any ` 运行时类型,那么整个函数返回的类型就是 ` R ` 。如果 ` T ` 都不满足 ` (...args: any) => any ` 这个结构,比如 ` GetFirstParamType<number> ` ,那这种推导根本无从谈起,直接返回 ` never ` 类型兜底,当然也可以自定义比如 ` any ` 之类的任何类型。
You can’t perform that action at this time.
0 commit comments