假设定义了以下类型:
interface Shape {
color: string;
}
现在,考虑以下方法来向该类型添加附加属性:
扩大
interface Square extends Shape {
sideLength: number;
}
交叉口
type Square = Shape & {
sideLength: number;
}
这两种方法有什么区别?
而且,为了完整性和好奇心,还有其他方法可以产生类似的结果吗?
是的,有些差异可能与您的场景相关,也可能无关。
也许最重要的是,当两种类型中都存在具有相同属性键的成员时,它们的处理方式有所不同。
考虑:
interface NumberToStringConverter {
convert: (value: number) => string;
}
interface BidirectionalStringNumberConverter extends NumberToStringConverter {
convert: (value: string) => number;
}
上面的扩展
会导致错误,因为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`
游乐场链接
这导致了另一个有趣的区别,接口
声明是开放式的。可以在任何地方添加新成员,因为合并了同一声明空间中具有相同名称的多个接口
声明。
下面是合并行为的常见用法
自由党。d、 ts
interface Array<T> {
// map, filter, etc.
}
数组平面映射多边形填充。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
子句,尽管在单独的文件中指定了接口,但这些接口都在全局范围内,并按名称合并到一个包含两组成员的逻辑接口声明中。(对于语法稍有不同的模块范围声明也可以这样做)
相反,存储在类型
声明中的交叉口类型是关闭的,不需要合并。
有很多很多的不同。您可以在TypeScript手册中阅读有关这两种构造的更多信息。接口和高级类型部分特别相关。
我需要为对后端服务器的HTTP请求创建某种类型(使用Angular 2),例如:}, 我应该用什么来构建这些模型?谢谢!
为什么它这样做,它有一个更好的做法?在sub接口中实现方法有什么区别吗?
有人知道如何扩展dropwizard界面吗?现在它只有所需的选项,但我需要为anooted方法添加权限。 例如: 我有一个用户管理员和一个普通用户。两者都可以进行身份验证并到达我的@auth带注释的资源。但我想允许一些(不是全部)http方法请求只为管理员和普通用户删除。如何在资源之外执行此操作?类似的东西
主要内容:org.springframework.context.ApplicationContextInitializer,org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor,org.springframework.beans.factory.config.BeanFactoryPostProcessor,,,,,,,,,,,,1.可扩展的接口启动调用顺序图 ApplicationConte
主要内容:org.springframework.context.ApplicationContextInitializer,org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor,org.springframework.beans.factory.config.BeanFactoryPostProcessor,,,,,,,,,,,,1.可扩展的接口启动调用顺序图 ApplicationConte
主要内容:TypeScript,JavaScript,联合类型和接口,TypeScript,JavaScript,接口和数组,实例,实例,TypeScript,接口继承,TypeScript,JavaScript,TypeScript,JavaScript接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。 TypeScript 接口定义如下: 实例 以下实例中,我们定义了一个接口 IPe