Now that typescript 3.1 introduced mapped tuple types, I was hoping this code sample would work:
export interface SettingKey {
General_Language: 'en' | 'sl';
Map_InitialLongitude: number;
Map_InitialLatitude: number;
}
export function fetchSetting<K extends (keyof SettingKey)[]>
(...keys: K): Promise<SettingKey[K]> {
return null as any;
}
fetchSetting('General_Language', 'Map_InitialLongitude').then(x => {
return x['General_Language'] === 'de' // would want compilation error 'de' not in 'en' | 'sl'
})
But it doesn't. The errors are:
ttt.ts:7:83 - error TS2536: Type 'K' cannot be used to index type 'SettingKey'.
7 export function fetchSetting<K extends (keyof SettingKey)[]>(...keys: K): Promise<SettingKey[K]> {
~~~~~~~~~~~~~
ttt.ts:11:12 - error TS2571: Object is of type 'unknown'.
11 return x['General_Language'] === 'de'
~
Clearly the second error is a consequence of the first one, so that's not really a concern. The first one is the problematic one.
keys is an array of keyof SettingKey
, and so I would hope that SettingKey[K]
would be an array of the types of the listed properties (so, concretely in the code sample I put, it would be ['en' | 'sl', number]
. From the pull request introducing the typescript feature:
If T is an array type S[] we map to an array type R[], where R is an instantiation of X with S substituted for T[P].
But that holds I guess for mapped types only, and here I have a lookup type, that would be the reason why it doesn't work I guess?
I think what I want to express is clear; can this be made type-safe in typescript?