lis*_*aak 5 polymorphism inheritance typescript union-types
我正在 Typescript 中使用联合类型,我刚刚意识到它们可以用来表达多态性而不是继承。从 Java 开始,我会写这样的东西。
interface Smiley {
print(): string;
}
class Happy implements Smiley {
print() {
return ':-)';
}
}
class Sad implements Smiley {
print() {
return ':-(';
}
}
Run Code Online (Sandbox Code Playgroud)
另一方面,我可以用工会表达同样的事情
class Happy {
print() {
return ':-)';
}
}
class Sad {
print() {
return ':-(';
}
}
type Smiley = Happy | Sad;
Run Code Online (Sandbox Code Playgroud)
这些方法之间的理论或实践差异是什么?
我想到的是第一个允许 Smiley 类型的值是任何实现 Smiley 接口的值。第二个只允许笑脸高兴或悲伤,除此之外别无其他。
我还缺少什么吗?
有了这些特定的属性,没有太大区别。Smiley将表现得像类型{ print: () => string }. 两个版本都不会强制它,因此 Happy 和 Sad 是唯一与该类型匹配的东西;有人总是可以使用返回字符串的打印函数编写一个新对象,并且它将匹配Smiley
但是一旦您开始添加更多属性,它们的行为就不会相同。如果您向这两个类添加公共属性,则示例 2 将自动在 Smiley 中包含该属性。但在示例 1 中,只有将 Smiley 添加到 Smiley 时,Smiley 才会获得额外的属性,而将其添加到 Happy/Sad 则不会获得额外的属性。
或者更重要的是它们具有一些不同的属性。这就是工会最有用的地方。类型之间共享的任何属性都可以访问,而不会出现打字稿抱怨,但是除非您进行适当的检查来缩小类型范围,否则无法访问唯一的属性。
class Happy {
print() {
return ':-)';
}
greet() {
return 'hi';
}
}
class Sad {
print() {
return ':-(';
}
exterminate() {
return 'bye';
}
}
type Smiley = Happy | Sad;
const example: Smiley = /* some object; maybe it's a Happy, maybe it's a Sad, maybe something else matching Smiley*/
example.print(); // Allowed by typescript
if ('greet' in example) {
example.greet(); // Allowed, because we have narrowed it down to a Happy
}
example.exterminate(); // Not allowed, because I have no code to confirm it's a Sad
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1135 次 |
| 最近记录: |