interface TestObject {
person: {
firstName: string;
lastName: string;
address: {
country: string;
city: string;
street: string;
}
}
id: string;
}
const t: TestObject = {} as any;
type K<T> = T extends object ? keyof T : never;
function f<T, K1 extends K<T>>(object: T, key: K1): T[K1];
function f<T, K1 extends K<T>, K2 extends K<T[K1]>>(object: T, key1: K1, key2: K2): T[K1][K2];
function f<T, K1 extends K<T>, K2 extends K<T[K1]>, K3 extends K<T[K1][K2]>>(object: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
// ...
function f() {
return 1 as any;
}
const result1 = f(t, 'person', 'address');
/*
const result1: {
country: string;
city: string;
street: string;
}
*/
const result2 = f(t, 'id', '');
/*
Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345)
*/
Can the same be done without "death by a thousand overloads"? If there was something like Tail<T> type alias for const tuples, i think i know how i could do it.