2017-03-01 97 views
2

为什么空接口不要求对象为空?空接口允许任何对象?

interface A {}; 
const a: A = {a: 1}; 
console.log(a); 

是有效代码,将输出{ a: 1 }

我认为增加可选属性应该能正常运行,但

interface A {}; 
interface B extends A { 
    b?: any; 
} 
const a: B = {a: 1}; 
console.log(a); 

错误Type '{ a: number; }' is not assignable to type 'B'结束。

  • 如果接口定义什么属性对象必须有,B的情况下应该可以正常工作,所有必需的属性都存在。
  • 如果接口定义了对象可以具有的属性,则应导致错误,a未在接口中定义。

非空接口定义了对象可以和必须拥有的对象。 空接口的行为类似于any

是否有解释为什么空界面如此表现?这是故意的还是只是一个错误?

+0

空接口没有定义任何约束并适用于任何对象。虽然我不确定它的效用。 – rageit

回答

2

全部细节此行为是故意的。

当目标为空对象类型时,不会执行额外的属性检查,因为它很少只是允许空对象的意图。


其实,你可以分配{a: 1} B,这里其他的答案大多是错误的。

您已经打字稿在另一个稍微有一些混乱怪癖迷迷糊糊的,即你不能直接分配对象文本类型,其中的文字对象包含其他属性比类型指定的一个。

但是,只要符合类型,就可以将对象的任何现有实例指定给某个类型。

例如:

interface Animal { 
    LegCount: number; 
} 

let dog: Animal = { LegCount: 4, Fur: "Brown" }; // Nope 

var myCat = { LegCount: 4, Fur: "Black" }; 
let theCat: Animal = myCat; // OK 

这种约束会被忽略乳清你有一个类型,它是空的。

阅读全文herehere

来自Typescript团队的原始答案可在GitHub上找到。

+0

谢谢你的链接。但是这个解释并不完整。为什么情况A直接分配文字与界面工程中未指定的属性? – mleko

+0

@mleko因为A是空的。所以TS不关心只能在直接赋值的对象字面值中声明已知属性的规则。 – Alex

+0

但为什么空界面如此特别?它是故意的(如果是的话,意图是什么)或者它恰好以这种方式工作? – mleko

1

好的,有趣的问题。

测试案例1:

interface A {}; 
interface B extends A { 
    b?: any; 
} 
const a: A = {a: 1}; 
console.log(a); 

它传递,为A是一个空的接口,无论你哑巴里面会即可返回。工程就像一个classObject

测试案例2:

interface A {}; 
interface B extends A { 
    b?: any; 
} 
const a: A = {b: 1}; 
console.log(a); 

价值a只是改为b只是为了证明第一个测试用例。它通过。

测试案例3:

interface A {}; 
interface B extends A { 
    b?: any; 
} 
const a: B = {a: 1}; 
console.log(a); 

它失败了,因为里面有接口AB没有道具名为a

测试案例4:

interface A {}; 
interface B extends A { 
    b?: any; 
} 
const a: B = {b: 1}; 
console.log(a); 

它通过,作为界面B有一个名为b

我希望这可以帮助你理解。 PS:道具是指财产。

以此作为比喻:Interface A是一个空房子,无论你想要什么都可以。它不会说一个字。 Interface B是一个殖民地的房子,这意味着它需要特定的尺寸,形状和需要坚持Interface A。这意味着界面B不会更空,并受到规则的限制。

0

这是在Typescript中工作的方式。它基于结构分类。

总之

B实例是与A兼容如果B实现了所有由A所需的成员。

由于A不需要任何会员,所有对象都与A兼容。在this documentation

+1

B也不需要任何成员,但B case导致错误。接口不仅要求,而且还有限制。您只能使用在界面中定义的属性。恕我直言,因为A没有定义任何你不应该使用的财产。 – mleko

+0

不幸的是,这是你的意见,而不是打字稿类型系统的工作方式:)。没有“限制”这样的东西 –

+1

如果没有限制B case导致错误的原因?如果接口只需要什么属性对象应该有B案件应该很好,我定义了所有必需的属性。 – mleko