-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
Search Terms:
unique symbol, literal, widen, reassign, const, readonly
Code
const t1 = Symbol("t1")
const t1Copy = t1
const result1: typeof t1 = t1 // no error
const result2: typeof t1 = t1Copy // error: type symbol not assignable to unique symbol
class T2 {
static readonly sym = Symbol("T2")
readonly kind = T2.sym
}
const inst = new T2()
const result3: typeof T2.sym = T2.sym // no error
const result4: typeof T2.sym = inst.kind // error: type symbol not assignable to unique symbol
declare function genericIdentity<T>(arg: T): T
const unexpectedError: typeof t1 = genericIdentity(t1)
declare function genericSymbolNested<T extends symbol>(arg: T): { prop: T }
const unexpectedError2: { prop: typeof t1 } = genericSymbolNested(t1)Expected behavior:
No errors. t1Copy and inst.kind should retain their respective literal unique symbol types the same way string literals would because they are declared with const and readonly.
Actual behavior:
Errors on result2 and result4 because t1Copy and inst.kind are widened to symbol. When assigning a unique symbol variable to a new variable the type is always widened to symbol unless an explicit type annotation is added.
Playground Link:
Link
Related Issues:
Did not notice any similar bug reports, but the design notes from #17501 seem to confirm that the current behavior is a bug:
- Like literal types, these types contain "freshness" which can be widened away to produce a "regular" type.
- When you alias a symbolic const with another const, it has the type
typeof [[that original variable]].
Which implies they should work like other literal types which would not be widened in the example above.