Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Typescript中使用联合类型时如何重用代码_Typescript - Fatal编程技术网

在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()


总之,您可以拥有具有或不具有代码重用以及具有或不具有类层次结构的联合类型;最好将它们分开考虑