【发布时间】:2020-05-11 15:04:38
【问题描述】:
想象以下代码 (playground):
type AvailableTypes = {
'array': Array<any>;
'string': string;
'object': object;
}
class Wrapper<T extends keyof AvailableTypes> {
// Is either array, string or object
private readonly type: T;
// ERROR: Property 'value' has no initializer and is not definitely assigned in the constructor.
private readonly value: AvailableTypes[T];
constructor(type: T) {
this.type = type;
/**
* ERROR:
* TS2322: Type 'never[]' is not assignable to type 'AvailableTypes[T]'.
* Type 'never[]' is not assignable to type 'never'.
*/
switch (type) {
case 'array':
this.value = [];
break;
case 'string':
this.value = '';
break;
case 'object':
this.value = {};
break;
}
}
}
主要有两个错误:
TS2322:类型“never[]”不可分配给类型“AvailableTypes[T]”。
类型 'never[]' 不能分配给类型 'never'
即使AvailableTypes[T] 总是解析为AvailableTypes 中声明的类型之一,T 是它的关键。
...和
属性“值”没有初始化器,也没有在构造函数中明确赋值。
虽然type 是强制性的,并且必须是string、array 或object.
我在这里错过了什么?
可能相关的 SO Threads:
- Typescript Generic Union
- Create union out of interface using tag generic
- TypeScript: use of generic and union types
更新
(更新为@jcalz answer)
应该可以根据type 属性对value 进行类型检查:
// In the Wrapper class, should work since value can only be an array if type is 'array':
public pushValue(val: unknown) {
if (this.type === 'array') {
this.value.push(val);
}
}
【问题讨论】:
标签: typescript generics union-types