这是一个简单的程序:
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接口属性类型,但这似乎是一个任意限制。
有人可以解释为什么存在这种限制吗?
答案 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 说 hahaha ,因为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 实例,那么它就是一个无法解决的难题。但是类型系统,特别是结构系统,在描述实例身份方面非常糟糕。您可以在某个系统中为每个符号实例命名,但是您仍然没有办法描述在每次调用时返回新符号的函数。一般来说,你会很难使用第一个代码片段之类的代码,因为类型系统会假设调用两次的相同函数产生两个实际相同的对象。