Description
EDIT: The example code below mostly does work as per #20721 (comment). The only part remaining unsolved is that there is no equivelent of keyof
for unique symbols. The suggestion is to add a symbolof
type operator.
TypeScript Version: 2.7.0-dev.20171215
Thanks to #15473, unique symbols and string consts can be used as keys in types. But they don't work with indexed access types or index type queries (#11929), as demonstated below.
Code
const SYM = Symbol('A Symbol');
const STR = 'A String';
interface Foo {
'lit': string;
[STR]: boolean;
[SYM]: number;
}
declare let foo: Foo;
let v1 = foo['lit']; // v1 is string
let v2 = foo[STR]; // v2 is boolean
let v3 = foo[SYM]; // v3 is number
// indexed access types
type T1 = Foo['lit']; // T1 = string
type T2 = Foo[STR]; // ERROR: Cannot find name 'STR'
type T3 = Foo[SYM]; // ERROR: Cannot find name 'SYM'
// index type query
type K = keyof Foo; // K = 'A string' | 'lit' (but no SYM)
Expected behavior:
No errors. T2
is boolean
and T3
is number. keyof Foo
is 'A string' | 'lit' | SYM
Actual behavior:
Errors for T2
and T3
, and keyof Foo
doesn't include SYM
.
I know there are several overlapping features in play here, but would like to know if all of the actual behaviour above is by design. E.g., maybe not having symbols show up in keyof
queries is by design, but what about the fact that we can't query types with Foo[STR]
or Foo[SYM]
, even though the compiler knows the types and the syntax is consistent with Foo['lit']
?