为什么打字稿在界面中使用自定义符号有限制?

时间:2016-12-30 20:53:09

标签: typescript typescript2.0

这是一个简单的程序:

const mySymbol = Symbol();
interface Fails {
  [mySymbol]: boolean;
}

interface Succeeds {
  [Symbol.hasInstance]: boolean;
}

以下是compling的输出:

$ tsc --lib es6 odd.ts
odd.ts(3,3): error TS1169: A computed property name in an interface must directly refer to a built-in symbol.

错误是可以理解的,只有内置符号可以用作Typescript接口属性类型,但这似乎是一个任意限制。

有人可以解释为什么存在这种限制吗?

1 个答案:

答案 0 :(得分:4)

考虑一些代码:

// Implementation not visible to us
declare function getSymbol(): Symbol;

const s1 = getSymbol();
const s2 = getSymbol();

interface Type1 {
  [s1]: string;
  [s2]: number;
}

这个声明合法吗?我们问一些朋友。

Alice ,因为getSymbol每次调用时都会返回不同的符号,因此s1和{{1创建两个单独的属性槽。

Bob 没有,因为s2每次调用时都会返回相同的符号,因此getSymbol和{{ 1}}是相同属性的冲突声明。

Eve haha​​ha ,因为s1会随机返回两个不同符号中的一个,所以谁知道发生了什么。

谁对吗?我不知道。没人做到。我们只是在猜测,因为我们无法看到s2的实现。即使我们可以,它的实施也可能是任意复杂的。

此外,即使我们可以描述getSymbol的行为,我们仍然无法解释此代码:

getSymbol

也许getSymbol// Implementations not visible to us declare function getSymbol1(): Symbol; declare function getSymbol2(): Symbol; const s1 = getSymbol1(); const s2 = getSymbol2(); interface Type1 { [s1]: string; [s2]: number; } 会返回相同的符号。也许他们没有。也许他们有时会这样做谁知道?如果没有一种方法可以明确地命名单个Symbol 实例,那么它就是一个无法解决的难题。但是类型系统,特别是结构系统,在描述实例身份方面非常糟糕。您可以在某个系统中为每个符号实例命名,但是您仍然没有办法描述在每次调用时返回新符号的函数。一般来说,你会很难使用第一个代码片段之类的代码,因为类型系统会假设调用两次的相同函数产生两个实际相同的对象。