您可以使用类型别名:
interface Ask {
price: number;
amount: number;
}
type Bid = Ask;
Playground link个
请注意,因为TypeScrip的类型系统是structural(基于类型的shape),而不是nominative(基于类型的名称/标识),所以类型为Ask
的对象将可以赋给Bid
个变量/属性/参数,反之亦然.TypeScrip没有区分它们:
let a: Ask = { price: 42, amount: 2 };
// ^? −−− let a: Ask
let b: Bid = { price: 67, amount: 4 };
// ^? −−− let b: Ask
a = b; // <== This is allowed
请注意,显示的b
类型提示是Ask
,而不是Bid
.
如果您想区分这两种类型,可以使用Drew Colthorp在文章Flavoring: Flexible Nominal Typing for TypeScript中描述的技术(感谢VLAZ指出这一点;另请参阅Vlaz‘s answer to a related question).它的核心是您可以通过使用optional品牌属性来区分类型,如下所示(但请继续阅读):
interface Offer {
price: number;
amount: number;
}
interface Bid extends Offer {
__type__?: "Bid";
}
interface Ask extends Offer {
__type__?: "Ask";
}
由于该属性是可选的,因此您不必在创建实例时指定它,但它会使类型彼此不兼容(尽管您可以很容易地从一个类型转换为另一个类型):
let a: Ask = { price: 42, amount: 2 };
// ^? −−− let a: Ask
let b: Bid = { price: 67, amount: 4 };
// ^? −−− let b: Bid
a = b; // <== Error: Type 'Bid' is not assignable to type 'Ask'.
// Types of property '__type__' are incompatible.
// Type '"Bid" | undefined' is not assignable to type '"Ask" | undefined'.(2322)
Playground link个
在这篇文章中,Colthorp进一步创建了一个可重用的泛型Flavor
类型:
interface Flavoring<FlavorT> {
_type?: FlavorT;
}
type Flavor<T, FlavorT> = T & Flavoring<FlavorT>;
您将在代码中使用它,如下所示:
interface Offer {
price: number;
amount: number;
}
type Bid = Flavor<Offer, "Bid">;
type Ask = Flavor<Offer, "Ask">;
Playground link个
对a
和b
的相同测试表明,您不能将一个分配给另一个.
最后,您可以通过在实例中实际包含_type
(或__type__
)属性而不使它们成为可选项来使用全品牌类型.我发现有时这样做很方便,因为我可以在调试器中看到这些属性,并且可以在使用Offer
个实例的代码中使用它们来缩小类型范围.但有时您不想让额外的属性弄乱对象,因此采用了上面的"风格"方法.完整的品牌推广示例:
interface Offer {
price: number;
amount: number;
}
interface Bid extends Offer {
__type__: "Bid";
}
interface Ask extends Offer {
__type__: "Ask";
}
let a: Ask = { price: 42, amount: 2, __type__: "Ask" };
// ^? −−− let a: Ask
let b: Bid = { price: 67, amount: 4, __type__: "Bid" };
// ^? −−− let b: Bid
a = b; // <== Error: Type 'Bid' is not assignable to type 'Ask'.
// Types of property '__type__' are incompatible.
// Type '"Bid"' is not assignable to type '"Ask"'.(2322)
Playground link个