Closed
Description
Bug Report / Feature Request
When indexing a mapped type that is meant to have the same keys as an original type, the compiler emits errors when using a generic type which is a key of the original type:
Playground Link with Demonstration
Static Code Sample
export interface Original {
prop1: {
subProp1: string,
subProp2: string
},
prop2: {
subProp3: string,
subProp4: string
}
}
export type KeyOfOriginal = keyof Original;
export type NestedKeyOfOriginalFor<T extends KeyOfOriginal> = keyof Original[T]
export const getStringFromOriginal = <K extends KeyOfOriginal, N extends NestedKeyOfOriginalFor<K>>(original: Original, key: K, nestedKey: N): Original[K][N] {
return original[key][nestedKey];
}
export type SameKeys<T> = {
[K in keyof T]: {
[K2 in keyof T[K]]: number;
}
}
export type MappedFromOriginal = SameKeys<Original>;
/**
* This method should work, as K and N are guaranteed to be valid keys of both Original and MappedFromOriginal
*
* The way the types are setup, it is invalid to construct an instance of MappedFromOriginal which has extra properties or is missing a property
*
* This example also works if I don't use nested keys, just one level of key mapping is fine. 2 levels of key mapping breaks.
*/
export const getStringAndNumberFromOriginalAndMapped =
<K extends KeyOfOriginal, N extends NestedKeyOfOriginalFor<K>>(
original: Original,
mappedFromOriginal: MappedFromOriginal,
key: K, nestedKey: N
): [Original[K][N], MappedFromOriginal[K][N]] => { // Type 'N' cannot be used to index type 'SameKeys<Original>[K]'
return [original[key][nestedKey], mappedFromOriginal[key][nestedKey]] // Type 'N' cannot be used to index type 'SameKeys<Original>[K]'
}