File tree Expand file tree Collapse file tree 1 file changed +3
-3
lines changed Expand file tree Collapse file tree 1 file changed +3
-3
lines changed Original file line number Diff line number Diff line change @@ -36,10 +36,10 @@ function xxx<T>(value: T): { result: T }
36
36
37
37
但我们发现 ` T ` 这个泛型太整体化了,我们还不具备从中 Pick 子类型的能力。也就是对于 ` xxx<{label: string}> ` 这个场景,` T = {label: string} ` ,但我们无法将 ` R ` 定义为 ` {label: R} ` 这个位置,因为泛型是一个不可拆分的整体。
38
38
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 ` 结合起来用,即:
40
40
41
41
` ` ` typescript
42
- type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never
42
+ type GetLabelTypeFromObject<T> = T extends { label: infer R } ? R : never
43
43
44
44
type Result = GetLabelTypeFromObject<{ label: string }>;
45
45
// type Result = string
@@ -50,7 +50,7 @@ type Result = GetLabelTypeFromObject<{ label: string }>;
50
50
回过头来看第一个需求,拿到第一个参数类型就可以用 ` infer ` 实现了:
51
51
52
52
` ` ` 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
54
54
` ` `
55
55
56
56
可以理解为,如果此时 ` 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