I am building an API abstraction using Typescript Generics but am struggling to find an elegant syntax to get things working as I would like. Here is a dummied up version of what I have managed to get working. Any ideas of how to simplify things?
interface ExampleInterface {
LevelOne: {
LevelTwo: {
keyOne: string;
keyTwo: number;
keyThree: boolean;
}
}
}
class ExampleClassOne <T1, K1 extends keyof T1> {
requestMethod<K2 = 'LevelTwo'> (): Promise<K2 extends keyof T1[K1] ? T1[K1][K2] : any> {
return new Promise (async (resolve, reject) => {
try {
const requestResponse = await axios({
url: `https://someurl.com/api/`,
method: 'GET'
})
resolve(requestResponse.data)
} catch (err) {
reject(err.response.status);
}
})
}
}
class ExampleClassTwo {
methodObj = {
levelOne: new ExampleClassOne<ExampleInterface, 'LevelOne'>()
}
}
In particular this bit of code is bothering me:
Promise<K2 extends keyof T1[K1] ? T1[K1][K2] : any>
I would like it to look more like this:
Promise<T1[K1][K2]>
I am still trying to get my head around Typescript and would appreciate some kind of explanation as to what kind of sorcery is playing out here. Why does it require this conditional type guard for the second level of nesting?
Many thanks.