我正在尝试继承将使用 IModal、IEmbedded 或 ITab 扩展的基本接口(interface) IScreen,并锁定方法以便它们特定于接口(interface)。但是发生的是 public OpenModal(modal: IModal)
方法出于某种原因只接受任何类型。
namespace Framework {
"use strict";
interface IScreen { }
interface IModal extends IScreen { }
interface ITab extends IScreen { }
interface IEmbedded extends IScreen { }
class BaseScreen implements IScreen {
public HandleCloseEvent() {
}
}
class DetailsScreen extends BaseScreen implements IModal {
}
class ListScreen extends BaseScreen implements IEmbedded {
}
class OpenerService {
public OpenScreen(screen: IScreen) {
}
public OpenModal(modal: IModal) {
}
}
class Controller {
constructor(openerService: OpenerService) {
var detailsScreen: DetailsScreen = new DetailsScreen();
var listScreen: ListScreen = new ListScreen();
openerService.OpenModal(212121); // Expected error
openerService.OpenModal(listScreen); // Expected error
}
}
}
- 我是否遗漏了一些我没有的编译器配置 收到任何错误?
- 我是否误解了界面的工作原理?
最佳答案
这就是 TypeScript 的工作方式:使用结构化类型(也称为鸭子类型)。
您声明:
public OpenModal(modal: IModal) {
}
因为你所有的接口(interface)都是空的,所以相当于写:
public OpenModal(modal: {}) {
}
这个签名接受每个对象,因为所有对象都兼容一个空对象。 212121
是一个对象(在 JavaScript 中,数字是一个对象)。 listScreen
也是一个对象。
您会注意到为空对象类型声明多个接口(interface)是没有用的:
interface IScreen { }
interface IModal extends IScreen { }
interface ITab extends IScreen { }
interface IEmbedded extends IScreen { }
在这里,你所有的接口(interface)都是等价的。没有等级制度。你可以这样做:
let a: IScreen
let b: IModal
let c: IModal = a // type '{}' ('IScreen') is compatible to type '{}' ('IModal')
let d = {}
let e: IModal = d // type '{}' is compatible to type '{}' ('IModal')
另见:
关于javascript - 为什么接口(interface)参数允许任何类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42555103/