在Typescript接口中禁止使用属性

时间:2015-04-28 17:34:53

标签: interface typescript typescript1.4

我要创建一个TypeScript接口,它不仅要求存在特定属性,还要禁止不属于定义的属性。这是一个例子:

  export interface IComponentDirective {
    scope : any;
    templateUrl : string;
  };

  var ddo : IComponentDirective = {
    scope: {
      dt: '='
    },
    templateUrl: 'directives.datepicker',
    controller: function() {
      console.log('hello world');
    }
  };

即使接口中未定义controllerddo分配也不会引发错误。做一些研究,看起来可能是设计的:

  

请注意,我们的对象实际上具有比此更多的属性,但是   编译器只检查至少存在所需的那些   并匹配所需的类型。

     

http://www.typescriptlang.org/Handbook#interfaces

但请注意,在我将ddo声明为IComponentDirective后,如果我尝试以下内容:

ddo.transclude = false;

发布者会抱怨:

  

2339财产'转移'在类型上不存在   ' IComponentDirective'

有没有办法强制执行更严格的合同?

1 个答案:

答案 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;