'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