Consider the following code:
// The actual implementation is hidden from us
declare function getSymbol(): Symbol;
const s1 = getSymbol();
const s2 = getSymbol();
interface Type1 {
[s1]: string;
[s2]: number;
}
Is this declaration valid? Let's hear different opinions from our friends.
Alice believes yes, as she thinks that since getSymbol
returns a unique symbol each time, s1
and s2
will create separate property slots.
Bob disagrees with no, stating that getSymbol
always gives the same symbol on each invocation, making s1
and s2
conflicting declarations for the same property.
Eve finds it amusing with a hahaha, suggesting that since getSymbol
randomly chooses between two symbols, the outcome is unpredictable.
Who is correct? It remains uncertain. Speculations arise because the inner workings of getSymbol
are unknown. Even if we could access its implementation, it may have intricate complexities.
Furthermore, even if we could define the behavior of getSymbol
, resolving issues in code like this proves challenging:
// 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;
}
Perhaps getSymbol1
and getSymbol2
yield the same symbol, or maybe they don't consistently. Without a way to uniquely identify individual instances of Symbol, it presents an unsolvable puzzle. Structural type systems struggle to depict instance identities effectively. You might establish a system where symbol instances are named individually, but describing a function that produces a new symbol per call remains challenging. In general, dealing with code similar to the first snippet poses difficulty for type systems assuming the same function invoked twice generates two nearly identical objects.