【发布时间】:2019-04-30 04:57:31
【问题描述】:
我的目标是使用严格类型来确保对象的格式正确。我希望能够指定一些必须遵循并强制执行的有效格式。
interface TypeA { A: void; }
interface TypeB { B: void; }
interface TypeC { C: void; }
type Type = TypeA | TypeB | TypeC;
interface BaseItem<T extends Type> { name: string; data: T; }
type Item = BaseItem<TypeA> | BaseItem<TypeB> | BaseItem<TypeC>;
const collection: Item[] = [
{ name: 'A', data: { A: null } },
{ name: 'B', data: { B: null } },
{ name: 'C', data: { C: null } },
];
class Example<T extends Type> {
item: BaseItem<T>;
add(item: BaseItem<T>) {
this.item = item;
collection.push(item); // Error on `item`
/**
* Argument of type 'BaseItem<T>' is not assignable to parameter of type 'Item'.
* Type 'BaseItem<T>' is not assignable to type 'BaseItem<TypeA>'.
* Type 'T' is not assignable to 'TypeA'.
* Type 'Type' is not assignable to type 'TypeA'.
* Property 'A' is missing in the type 'TypeB' but required in type 'TypeA'.
*/
}
}
在上面的代码中,Item 类型用于强制collection 数组中对象的格式。这让我知道我打算如何使用这种格式。
同样在上面的代码中,我尝试对Example 类使用泛型。这个想法是我可能想要我的类的几个属性来确保它们在任何给定时刻都使用共享泛型。虽然泛型扩展了有效类型,但我知道它理论上可以支持超出它的类型(例如BaseItem<TypeA> & { more: string })。
我明白为什么它在当前状态下不起作用。我不明白我将如何完成我想要的。
有没有办法使用泛型来严格匹配一种联合而不是扩展一种联合?比如,不是<T extends Type>,而是<T is Type>?或者,有没有其他方法可以解决这个问题?
【问题讨论】:
-
您到底想解决什么问题?当前代码产生错误,因为
BaseItem是Item的子类型,而不是相反。我不明白为什么Type存在问题? -
如果你想要
T is Type,那么从字面上看,你不需要一个通用的cus,你已经知道它是Type。 -
最终目标是使用
T类型使类具有多个属性和方法。这将允许任何子类更具体(例如class Specific extends Example<TypeA> { ... })并强制遵守指定的任何类型。 -
如果我只是使用
Type,那么我将无法确保TypeA在应该只使用TypeA的子类中使用超过TypeB. -
那么你已经得到了你想要的,
<T extends Type>就是你所说的<T is Type>。就像我说的,你得到的错误与T无关
标签: typescript