是的,有些差异可能与你的情况有关,也可能与你的情况无关.
也许最重要的是,当两种类型中都存在具有相同属性键的成员时,它们的处理方式有所不同.
考虑:
interface NumberToStringConverter {
convert: (value: number) => string;
}
interface BidirectionalStringNumberConverter extends NumberToStringConverter {
convert: (value: string) => number;
}
上面的extends
会导致一个错误,因为derriving接口声明了一个属性,该属性的密钥与派生接口中的密钥相同,但签名不兼容.
error TS2430: Interface 'BidirectionalStringNumberConverter' incorrectly extends interface 'NumberToStringConverter'.
Types of property 'convert' are incompatible.
Type '(value: string) => number' is not assignable to type '(value: number) => string'.
Types of parameters 'value' and 'value' are incompatible.
Type 'number' is not assignable to type 'string'.
然而,如果我们采用交叉口类型
type NumberToStringConverter = {
convert: (value: number) => string;
}
type BidirectionalStringNumberConverter = NumberToStringConverter & {
convert: (value: string) => number;
}
没有任何错误,并进一步说明
// And this is a good thing indeed as a value conforming to the type is easily conceived
const converter: BidirectionalStringNumberConverter = {
convert: (value: string | number) => {
return (typeof value === 'string' ? Number(value) : String(value)) as string & number; // type assertion is an unfortunately necessary hack.
}
}
const s: string = converter.convert(0); // `convert`'s call signature comes from `NumberToStringConverter`
const n: number = converter.convert('a'); // `convert`'s call signature comes from `BidirectionalStringNumberConverter`
Playground Link
这导致了另一个有趣的区别,interface
个声明是开放式的.新成员可以添加到任何地方,因为在同一声明空间中有多个interface
个同名声明是merged个.
下面是合并行为的常见用法
lib.d.ts
interface Array<T> {
// map, filter, etc.
}
array-flat-map-polyfill.ts
interface Array<T> {
flatMap<R>(f: (x: T) => R[]): R[];
}
if (typeof Array.prototype.flatMap !== 'function') {
Array.prototype.flatMap = function (f) {
// Implementation simplified for exposition.
return this.map(f).reduce((xs, ys) => [...xs, ...ys], []);
}
}
请注意,不存在extends
子句,尽管在单独的文件中指定了这些接口,但它们都在全局范围内,并按名称合并到一个包含两组成员的逻辑接口声明中.(对于语法稍有不同的模块范围声明也可以这样做)
相比之下,存储在type
声明中的交叉点类型是关闭的,不需要合并.
有很多很多不同之处.您可以在TypeScript手册中阅读更多关于这两种 struct 的信息.Interfaces和Advanced Types部分特别相关.