TypeScript中new Millseconds(-1)为何提示参数类型为never?
问题解析:为什么
new Millseconds(-1)会触发never类型错误? 先看涉及的TypeScript代码:
type AssertPositive<N extends number> = number extends N ? N : `${N}` extends `-${string}` ? never : N; class Millseconds<N extends number> { constructor(public readonly value: AssertPositive<N>){ if(this.value < 0){ throw new Error('Value Cannot Smaller Than 0'); } } }
执行new Millseconds(-1)时,会报错:Argument of type 'number' is not assignable to parameter of type 'never',下面针对两个疑问逐一解释:
疑问1:为何参数-1的类型不进入number extends N ? N : ...分支?
当你调用new Millseconds(-1)时,TypeScript会自动推断泛型N的类型为字面量类型-1,而非宽泛的number类型。此时判断number extends N等价于判断number extends -1——显然不成立,因为number包含所有数字,-1只是其中一个具体值,所以不会进入第一个分支,转而执行后续逻辑。
疑问2:为何-1对应的参数类型为never?
进入后续分支后,会执行${N} extends -${string}的判断:
- 这里
N是-1,${-1}会被TypeScript转换为字符串字面量"-1" "-1"完全符合-${string}(以减号开头的任意字符串)的模式,所以条件成立,返回never类型
构造函数的参数类型被推断为never,而你传入的-1是数字字面量类型,自然会触发“不能将number类型赋值给never类型”的错误。
简单总结这个类型工具的逻辑:
- 只有当泛型
N是宽泛的number类型(比如new Millseconds<number>(100))时,才会走第一个分支返回N - 如果是具体的数字字面量,会检查是否为负数:负数返回
never,正数返回原类型
内容的提问来源于stack exchange,提问作者sanheart
相关产品推荐
相关产品推荐

