I have an interface like this...
export interface IMyInterface {
test1: {
test1Sub: {
test1SubSub: string
}
},
test2: {
test2Sub: {
test2SubSub: string
}
}
}
I would like to be able to strongly type the names of the nested levels into a generic function to give TypeScript intellisense something like this which is in a generic class passing in Type T.
getSetting = (level1: keyof T, level2: keyof keyof T) => {
console.log(level1, level2)
}
Is this possible? How I have it at the moment it gives me this warning, it works fine for 'test1' but not 'test1Sub;
settings.getPageSettings('test1', 'test1Sub')
Argument of type '"test1Sub"' is not assignable to parameter of type '"toString" | "valueOf" | "toLocaleString"'
CodePudding user response:
You don't want keyof keyof
for the sub-level as this will the the keys
of each type defined by keyof IMyInterface
, instead you want keyof T[K]
Here's a quick playground.
export interface IMyInterface {
test1: {
test1Sub: {
test1SubSub: string
}
},
test2: {
test2Sub: {
test2SubSub: string
}
}
}
function getSetting<T extends IMyInterface, K extends keyof T>(level1: K, level2: keyof T[K]) {
console.log(level1, level2)
}
// usage
const myInterface:IMyInterface ={
test1: {
test1Sub: {
test1SubSub: 'subsub1'
}
},
test2: {
test2Sub: {
test2SubSub: 'subsub2'
}
}
}
getSetting('test1', 'test1Sub');
getSetting('test2', 'test1Sub');
// ^^^^^^^^
// Argument of type '"test1Sub"' is not assignable to parameter of type '"test2Sub"'