79741269

Date: 2025-08-20 15:20:13
Score: 0.5
Natty:
Report link

You can help out type inference by tweaking makeInvalidatorRecord to be type-parameterized over the invalidators' argument types. This is easier to explain in code than prose.

Instead of this:

type invalidatorObj<T extends Record<string, unknown>> = {
  [K in keyof T]: T[K] extends invalidator<infer U> ? invalidator<U> : never;
};

You could use a type like this:

type invalidatorObjFromArgs<T extends Record<string, unknown[]>> = {
  [K in keyof T]: invalidator<T[K]>
};

And then have the type parameter of makeInvalidatorObj be a Record whose property values are argument tuples rather than entire invalidators.

Here's a complete example:

type invalidator<TArgs extends unknown[]> = {
  fn: (...args: TArgs) => any;
  genSetKey: (...args: TArgs) => string;
};

type invalidatorObjFromArgs<T extends Record<string, unknown[]>> = {
  [K in keyof T]: invalidator<T[K]>
};

const makeInvalidatorObj = <T extends Record<string, unknown[]>>(
  invalidatorObj: invalidatorObjFromArgs<T>,
) => invalidatorObj;

const inferredExample = makeInvalidatorObj({
  updateName: {
    fn: (name: string) => {},
    genSetKey: (name) => `name:${name}`,
    //          ^? - (parameter) name: string
  },
  updateAge: {
    fn: (age: number) => {},
    genSetKey: (age) => `age:${age}`,
    //          ^? - (parameter) age: number
  },
});
Reasons:
  • RegEx Blacklisted phrase (3): You can help
  • Long answer (-1):
  • Has code block (-0.5):
  • High reputation (-1):
Posted by: Matt Kantor