在Typescript中使用联合类型时如何重用代码
我通过阅读文档来学习联合类型 用于演示联合类型的代码如下:在Typescript中使用联合类型时如何重用代码,typescript,Typescript,我通过阅读文档来学习联合类型 用于演示联合类型的代码如下: interface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } declare function getSmallPet(): Fish | Bird; let pet = getSmallPet(); pet.layEggs(); 关于使用联合类型,发表了以下评论: 在传统的面向
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
declare function getSmallPet(): Fish | Bird;
let pet = getSmallPet();
pet.layEggs();
关于使用联合类型,发表了以下评论:
在传统的面向对象代码中,我们可能会在这两个方面进行抽象
通过创建类型的层次结构来创建类型。而这要多得多
显然,这也有点过分了
提到的传统面向对象代码可能如下所示:
class Animal {
layEggs(): void {console.log("laying eggs")};
}
class Bird extends Animal {
fly(): void {console.log("flying")};
}
class Fish extends Animal {
swim(): void {console.log("swimming")};
}
declare function getSmallPet(): Animal;
let pet = getSmallPet();
pet.layEggs();
function getSmallPet(): Fish | Bird {
return Math.random() < 0.5 ? new Fish() : new Bird()
};
我在传统的面向对象代码中看到的一个好处是代码重用的能力。例如,类似的layEggs
实现可以移动到超类,而不是在两个子类中重复
在typescript中使用联合类型时,我还没有找到一种实现类似代码重用的方法。有什么方法可以实现这一点吗?当您想要列举一些可能性时,请使用union,特别是可以通过公共属性轻松实现的可能性。联合类型不会阻止代码重用,无论是否使用
class
层次结构。这些概念有些正交
例如,我们可以让getSmallPet()
将可分配给Fish
或Bird
接口的对象放在一起,但仍然可以重用代码:
function getSmallPet(): Fish | Bird {
const eggLayer = { layEggs() { console.log("LAYING EGGS") } };
const flier = { fly() { console.log("FLYING") } };
const swimmer = { swim() { console.log("SWIMMING") } };
return Object.assign(eggLayer, Math.random() < 0.5 ? flier : swimmer);
}
你不会从中得到一种不特定的动物;你要么得到一条鱼
,要么得到一只鸟
而
Animal
和Fish | Bird
类型都允许您调用layEggs()
方法:
let pet = getSmallPet();
pet.layEggs(); // LAYING EGGS;
只有管接头类型Fish | Bird
可以通过类型防护装置轻松探测,以达到向下投射的等效效果:
if ("swim" in pet) {
pet.swim(); // SWIMMING, or maybe
} else { // notice, just "else" here, not "else if"
pet.fly(); // FLYING
}
如果你有一只动物
,你必须检查鸟的实例
和鱼的实例
,如果你的动物
被证明是其他物种,那么第三个子句的作用类似于投掷()。有了Fish | Bird
你就知道如果它不会swim()
,那么它肯定会fly()
总之,您可以拥有具有或不具有代码重用以及具有或不具有类层次结构的联合类型;最好将它们分开考虑