Skip to content

Commit cd543b1

Browse files
committed
fix typo
1 parent 1cf5e33 commit cd543b1

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

前沿技术/207.精读《Typescript infer 关键字》.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ function xxx<T>(value: T): { result: T }
3636

3737
但我们发现 `T` 这个泛型太整体化了,我们还不具备从中 Pick 子类型的能力。也就是对于 `xxx<{label: string}>` 这个场景,`T = {label: string}`,但我们无法将 `R` 定义为 `{label: R}` 这个位置,因为泛型是一个不可拆分的整体。
3838

39-
而且实际上为了类型安全,我们也不能允许用户描述任意的类型位置,**万一传入的类型结构不是 `{label: xxx}` 而是一个回调 `() => void`,那子类型推导岂不是建立在了错误的环境中。** 所以考虑到想要拿到 `{label: infer R}`,首先参数必须具备 `{label: xxx}` 的结构,所以正好可以将 `infer` 与条件判断 `T extends ? A : B` 结合起来用,即:
39+
而且实际上为了类型安全,我们也不能允许用户描述任意的类型位置,**万一传入的类型结构不是 `{label: xxx}` 而是一个回调 `() => void`,那子类型推导岂不是建立在了错误的环境中。** 所以考虑到想要拿到 `{label: infer R}`,首先参数必须具备 `{label: xxx}` 的结构,所以正好可以将 `infer` 与条件判断 `T extends xxx ? 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
4444
type 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` 之类的任何类型。

0 commit comments

Comments
 (0)