Typescript 接口中禁止的属性
Prohibited attributes in a Typescript Interface
我要创建一个 TypeScript 接口,它不仅要求存在特定属性,而且禁止不属于定义一部分的属性。这是一个例子:
export interface IComponentDirective {
scope : any;
templateUrl : string;
};
var ddo : IComponentDirective = {
scope: {
dt: '='
},
templateUrl: 'directives.datepicker',
controller: function() {
console.log('hello world');
}
};
即使接口中未定义 controller
,ddo
赋值也不会引发错误。做一些研究,这看起来可能是设计的:
Notice that our object actually has more properties than this, but the
compiler only checks to that at least the ones required are present
and match the types required.
但是请注意,在我将 ddo
声明为 IComponentDirective
之后,如果我尝试以下操作:
ddo.transclude = false;
转译器会抱怨:
2339 Property 'transclude' does not exist on type
'IComponentDirective'.
有什么方法可以执行更严格的合同吗?
简而言之(但取决于您对 "tighter" 的定义)您不能限制超出此范围的事情。
界面是一个合同,上面写着"if these members are not present, you aren't one of these"。如果您的对象恰好有其他成员,那很好;当您使用界面时,它们对您来说是不可见的。
例如(根据您的代码),当您键入 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 将为您创建的任何对象生成一个类型,然后强制执行该结构,除非您另有说明。
如果你想 "sometimes be a transclude
member" 你可以做到:
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;
我要创建一个 TypeScript 接口,它不仅要求存在特定属性,而且禁止不属于定义一部分的属性。这是一个例子:
export interface IComponentDirective {
scope : any;
templateUrl : string;
};
var ddo : IComponentDirective = {
scope: {
dt: '='
},
templateUrl: 'directives.datepicker',
controller: function() {
console.log('hello world');
}
};
即使接口中未定义 controller
,ddo
赋值也不会引发错误。做一些研究,这看起来可能是设计的:
Notice that our object actually has more properties than this, but the compiler only checks to that at least the ones required are present and match the types required.
但是请注意,在我将 ddo
声明为 IComponentDirective
之后,如果我尝试以下操作:
ddo.transclude = false;
转译器会抱怨:
2339 Property 'transclude' does not exist on type 'IComponentDirective'.
有什么方法可以执行更严格的合同吗?
简而言之(但取决于您对 "tighter" 的定义)您不能限制超出此范围的事情。
界面是一个合同,上面写着"if these members are not present, you aren't one of these"。如果您的对象恰好有其他成员,那很好;当您使用界面时,它们对您来说是不可见的。
例如(根据您的代码),当您键入 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 将为您创建的任何对象生成一个类型,然后强制执行该结构,除非您另有说明。
如果你想 "sometimes be a transclude
member" 你可以做到:
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;