never 类型通常表示不会发生的类型,但是下面官方提供的泛型例子有点看不明白 never 的用途了。
type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
? Return
: never;
这是一个泛型工具类,可以提取函数的返回值类型,但是函数的参数定义成 never 类型数组有些不懂了,看提供的例子,这个定义既能满足无参数函数,也能满足有参数函数。
type Num = GetReturnType<() => number>;
//type Num = number
type Str = GetReturnType<(x: string) => string>;
//type Str = string
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;
//type Bools = boolean[]
1
realJamespond 212 天前
写成 any[]不也行?
|
2
hahaFck OP @realJamespond 写成 any 我能理解,但是 never 不知道是什么意思,而且按照我的理解是这个函数定义是不支持传参的,但是例子的 type Str = GetReturnType<(x: string) => string>; 这段代码竟然也能通过,奇怪了。
|
3
realJamespond 212 天前
他这里 args: never[],后面用不上,只是限制参数为数组,不进行推测。如果后面要用到 args 推测应该不能写成 never 的
|
4
Pencillll 212 天前
这是 TS 里的一个不合理设计
函数的参数是逆变的,所以 (x: string) => string 可以赋值给 (...args: never[]) => infer Return 的原因是 never[] 可以赋值给 [string],而 never[] 可以赋值给 [string] 的原因是……就是这么设计的 其实在正常情况下 never[] 是不可以赋值给 [string] 的,但 TS 对于函数里的 ...arg 这种语法做了某些处理导致这种赋值成立 官方的原话是(第二段): https://github.com/microsoft/TypeScript/issues/48840#issuecomment-1270671527 SO 有个同样的问题: https://stackoverflow.com/q/78316282 |
5
Pencillll 212 天前
我根据官方的原话猜测一下 TS 的做法:TS 先假定两个函数的参数数量一致,在这种前提下可以把数组 never[] 当成和元组 [string] 长度一样的元组,也就是 [never],再尝试赋值,而 [never] 是可以赋值给 [string] 的,所以前面的赋值也就成立了
|