I've been playing with Inferring types of deeply nested object in Typescript.
Original code
const theme = {
button: { margin: { sm: "sm" } },
form: { padding: { sm: "sm1" } }
} as const;
type Theme = typeof theme;
const getStyle = <
K extends keyof Theme,
S extends keyof Theme[K],
M extends keyof Theme[K][S]
>(t: Theme, name: K, style: S, mod: M) => t[name][style][mod];
getStyle(theme, 'button', 'margin', 'sm');
I have introduced one variation from the original example - in my code leaf nodes always have the same structure {sm: string}
.
What I am struggling with is to modify getStyle
in such way that the client can specify only 2 levels of keys, and benefit from the fact that the structure of the nodes is always the same;
const getStyleNew = <
K extends keyof Theme,
S extends keyof Theme[K]
>(t: Theme, name: K, style: S) => t[name][style].sm;
Unfortunately, this fails with:
Property 'sm' does not exist on type '{ readonly button: { readonly margin: { readonly sm: "sm"; }; }; readonly form: { readonly padding: { readonly sm: "sm"; }; }; }[K][S]'.
Is there a way to convince the compiler that sm is available on t[name][style]
in the modified function?