为什么TypeScript与Object接口属性重新赋值不一致?

时间:2017-03-18 01:21:23

标签: typescript

通用

interface Interface {
  a: number;
}

场景1

let var1: Interface = {
  a: 0
};

const temp = {
  a: 1,
  b: 4
};

var1 = temp; // Compiler is fine with this

场景2

const var2: Interface = {
  a: 2
};

var2.b = 3; // This won't compile

我是唯一发现这与编译器行为方式不一致的人吗?

在第一个场景中,编译器并不关心额外b属性是否在var1变量中结束。

然而在第二种情况下,编译器不允许var2拥有额外的属性。

为什么存在这种不一致?

通过以下两种方法消除不一致是否可行:

  • 不允许第一种情况
  • 允许第二种情况

编辑1

我很欣赏目前的行为(一致或不一致,取决于你的观点)因为权衡而产生,现在已被广泛采用。

在某些情况下,有没有办法(或提供一种方法)选择防范方案1?

我认为我所寻找的是一种名义上的打字行为,而不是结构性行为。

我很欣赏TypeScript早期决定提供结构类型,但我想知道(在语言设计领域是一个非专业人士)的可行性,提供两者(结构和名义)的部分。

此问题是在考虑TypeScript版本 2.2.1 的情况下创建的。

1 个答案:

答案 0 :(得分:4)

编译器的第一个场景很好的原因是typescript是based on structural subtypingtemp的结构满足接口Interface

但是,如果您尝试访问b属性,则编译器会抱怨:

console.log(var1.b); // error: Property 'b' does not exist on type 'Interface'

错误消息与第二个方案的错误信息相同,并且确实是一致的。

以下是一个有用的示例:

interface Interface {
    a: number;
}

interface BetterInterface {
    a: number;
    b: number;
}

function fn(a: Interface) { }

let a: BetterInterface = {
    a: 0,
    b: 0
};
fn(a);

请注意BetterInterface不会扩展Interface,但编译器会从对象的结构中推断出来。