typescript - 子类型与其超类型的交集是否与子类型相同?
问题描述
给定以下 TypeScript 代码:
interface A { /* ... */ }
interface B extends A { /* ... */ }
type Mystery = A & B;
该类型的对象Mystery
应该具有的所有属性A
和所有属性,B
因为它是一个交集类型。类型的对象B
应该已经具有A
because的所有属性B extends A
。
Mystery
鉴于这些定义, type和 type之间有区别B
吗?
解决方案
对于第一个近似值,如果B extends A
,那么A & B
和B
是相同的。编译器甚至会考虑A & B
并B
相互分配:
function foo<A, B extends A>(u: B, m: A & B) {
u = m; // okay
m = u; // okay
}
虽然不相同:
function foo<A, B extends A>(u: B, m: A & B) {
var v: B;
var v: A & B; // error, not considered identical
}
在实践中,会出现编译器处理不同A & B
的情况。B
其中一些是被视为错误或设计限制的编译器实现细节;我得去挖掘这些。
但是一个特定的地方可能很容易不同,这与调用签名的交集如何被解释为A & B
可以以多种方式调用的重载函数有关,而具有调用签名的接口扩展往往只是覆盖父接口调用签名并且可以只能被称为一种方式。例如:B
interface A { method(p: any): void }
interface B extends A { method(): void }
这是允许的,因为参数较少的函数可以分配给参数较多的函数。该类型B
只看到零参数方法,因此您会得到以下行为:
declare const a: A;
a.method(0); // okay
declare const b: B;
b.method(); // okay
b.method(0); // error!
由于method()
在 中被覆盖B
,b.method()
因此没有参数是错误的(即使零参数方法可分配给多参数方法,您仍然不能故意调用具有太多参数的函数而没有警告)。
将此与交叉点进行比较:
type Mystery = A & B;
declare const m: Mystery;
m.method(""); // okay
m.method(); // okay
如果你检查m.method
,你会看到它有两个重载:
// 1/2 method(p: any): void
// 2/2 method(): void
因此可以通过两种方式中的任何一种调用。
推荐阅读
- node.js - 如何在没有任何缺点的情况下在 MongoDB 中正确地建立一对一的关系?
- ruby-on-rails - Mongoid 删除未保存的嵌入文档
- reactjs - Webpack 4:React 库的生产模式失败
- excel - 仅比较输入的第一个值的简单 Excel 数组示例
- python - 向 Google Cloud Vision 添加语言提示
- r - 如何在 R 中跨对角线添加矩阵(“将其对折”)?
- javascript - 如何将我的 Python 代码上传到我的 WiX 网站?
- linux - 需要在每条消息后关闭读取端的 linux FIFO
- android - 在首先按下不允许后如何授予对 react-native-camera 的访问权限?
- sql - 不再有假脱机空间错误 - 选择语句