'Stop typescript generics inside Records from "intersecting" all the keys for nested generic records
I want the nested generic to know about the parent Record's key, the desired behavior in the typesystem would work like this:
let c = {
"hey": {ext: `${parent.key === "hey"}` /*true*/},
"bye": {ext: `${parent.key === "bye"}` /*true*/}
}
But the actual behavior is this:
let c = {
"hey": {ext: `${parent.key === "hey"}` /*false, parent.key === "hey" | "bye"*/},
"bye": {ext: `${parent.key === "bye"}` /*false, parent.key === "hey" | "bye"*/}
}
How can I force typescript to only take the key that the object is defined under ?
Full Example TS Playground
const Components = {
Wrapper: (arg: { name: string; ofAge: number }) => {},
Button: (arg: { age: number; favorites: string[] }) => {},
};
export type ComponentList = 'Wrapper' | 'Button';
export type GetProps<T extends ComponentList> = Parameters<typeof Components[T]>[0];
type PropsKeys<T extends ComponentList> = string & Exclude<keyof GetProps<T>, 'children'>;
type getOperators<T extends ComponentList, N extends PropsKeys<T>> = `${string &
N}.${string & keyof GetProps<T>[N]}`;
type Logic<T extends ComponentList, N extends PropsKeys<T>> = Record<
N,
{
ext: getOperators<T, N>;
}
>;
const myFn = <T extends ComponentList, N extends PropsKeys<T>>(
logic: Record<T, Logic<T, N>>
) => {};
// favorites is not assignable to type 'Logic<"Button", "age">'.
// it Unions the available properties together, but I would like it to know that for the ext part only favorites or age applies
myFn({
Button: {
age: { ext: 'age.toString' },
favorites: { ext: 'favorites.length' },
},
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
