我要创建一个TypeScript接口,它不仅要求存在特定属性,还要禁止不属于定义的属性。这是一个例子:
export interface IComponentDirective {
scope : any;
templateUrl : string;
};
var ddo : IComponentDirective = {
scope: {
dt: '='
},
templateUrl: 'directives.datepicker',
controller: function() {
console.log('hello world');
}
};
即使接口中未定义controller
,ddo
分配也不会引发错误。做一些研究,看起来可能是设计的:
请注意,我们的对象实际上具有比此更多的属性,但是 编译器只检查至少存在所需的那些 并匹配所需的类型。
但请注意,在我将ddo
声明为IComponentDirective
后,如果我尝试以下内容:
ddo.transclude = false;
发布者会抱怨:
2339财产'转移'在类型上不存在 ' IComponentDirective'
有没有办法强制执行更严格的合同?
答案 0 :(得分:1)
简而言之(但根据您对&#34的定义;更严格的"),您可以限制超出此范围的内容。
界面是一份合同,上面写着"如果这些成员不在场,你就不是其中之一"。如果你的对象碰巧有其他成员,那很好;当您使用界面时,它们对您来说是不可见的。
例如(基于您的代码),当您键入ddo.
时,它只会建议接口上的成员,因为您告诉编译器使用接口类型。
您无法使用阻止成员定义的界面。我无法想到任何能够做到这一点的语言。例如,在C#中,您可以实现的不仅仅是要求您实现的接口,但是当您使用接口类型时,其他成员也不可用。
关于为什么ddo.tranclude = false;
生成警告的问题有点不同。这与接口无关 - 当没有接口时它会这样做:
var ddo = {
scope: {
dt: '='
},
templateUrl: 'directives.datepicker',
controller: function() {
console.log('hello world');
}
};
ddo.transclude = false; // Nope
原因是......这是TypeScript的重点!它警告您,您可能错误地键入了transclude
。也许你的意思是templateUrl
, 存在。如果TypeScript没有提醒您这类问题,那么它将允许您在代码中引入印刷错误。
因此TypeScript会为您创建的任何对象生成一个类型,然后强制执行该结构,除非您另有说明。
如果你想要#34;有时成为transclude
成员"你可以做到这一点:
interface SometimesTransclude {
scope: { dt: string};
templateUrl: string;
controller: () => void;
transclude?: boolean;
}
var ddo: SometimesTransclude = {
scope: {
dt: '='
},
templateUrl: 'directives.datepicker',
controller: function() {
console.log('hello world');
}
};
ddo.transclude = false;
或者您可以使用以下方式直接跳过编译器(风险自负):
ddo['transclude'] = false;