我想知道如果我添加了一个应该保证期望类型的约束,为什么TypeScript会将条件类型解析为never
。
示例
假设我们已经编写了这样的代码
type PrimitiveDataType = string | number | bigint | boolean | symbol | undefined | null;
type ConditionalType<T> = T extends PrimitiveDataType
? (v: T) => void
: never;
abstract class AbstractClass<T> {
abstract value: T;
protected conditionalFunctions: Map<ConditionalType<T>, number | undefined> = new Map();
}
class SomeClass<T extends PrimitiveDataType> extends AbstractClass<T> {
value: T;
constructor(value: T) {
super();
this.value = value;
}
someMethod() {
for (const someFn of this.conditionalFunctions.keys()) {
someFn(this.value);
}
}
}
在上面的代码中,我创建了一个PrimitiveDataType
,它是JavaScript中所有原始数据类型的并集。
然后,我创建了一个ConditionalType<T>
,只有当T
是PrimitiveDataType
之一时,它才会解析为某个回调。
然后我创建了一个抽象泛型类,它有一个类型(ConditionalType<T>
)依赖于该类泛型值的字段。
最后,我创建了一个SomeClass
,它扩展了AbstractClass<T>
,并添加了泛型参数T
必须扩展PrimitiveDataType
的约束,我得到了这个错误:
TS2345: Argument of type 'PrimitiveDataType' is not assignable to parameter of type 'never'.
Type 'undefined' is not assignable to type 'never'.
结论
我想如果在SomeClass
T
中有一个约束,它必须是PrimitiveDataType
上的一个,那么TypeScript将解析conditionalFunctions
字段为Map<(v: T) => void, number | undefined>
类型。令我惊讶的是,TypeScript将此类型解析为Map<(v: never) => void, number | undefined>
,这对我来说是不清楚的,我不知道哪里是错误的方式,我该怎么想?
你能给我解释一下为什么会这样吗?或者可能是TypeScript编译器的bug?
观察
如果我只留下一个,键入PrimitiveDataType
,那么一切正常,但对于多个,我得到一个错误
TypeScript游戏场链接
编辑1
如果我的条件类型有两个以上可能的返回类型,那么分布式[T]
就不起作用,并给出这样的错误:
Expected 2 arguments, but got 1.
看起来TS现在把这个类型解析成了Array的Map类型,我现在完全不明白
- 示例**
type PrimitiveDataType = string | number | bigint | boolean | symbol | undefined | null;
type ConditionalType<T> = [T] extends [PrimitiveDataType]
? (v: T) => void
: T extends Array<unknown>
? (v: T, t: number) => void
: never;
abstract class AbstractClass<T> {
abstract value: T;
protected conditionalFunctions: Map<ConditionalType<T>, number | undefined> = new Map();
}
class SomeClass<T extends PrimitiveDataType> extends AbstractClass<T> {
value: T;
constructor(value: T) {
super();
this.value = value;
}
someMethod() {
for (const someFn of this.conditionalFunctions.keys()) {
someFn(this.value);
}
}
}
TypeScriptPlayground链接编辑1
1条答案
按热度按时间rt4zxlrg1#
泛型类型
ConditionalType<T>
在给定联合时生成一个分布式类型。例如,给定并集
string | number
时,将生成以下类型请将条件的任意一侧括在方括号中以避免出现这种情况
上面的代码现在生成了下面的非分布式类型,它应该可以为抽象类工作
Playground