Search code examples
functiongenericstypescriptkeyof

Generic function and infering keyof generic in Typescript


I am trying to remove the second generic from the following function, because (IMHO) it should be possible to infer the K extends keyof T:

const normalizeToProps = <T, K extends keyof T>(...props:K[]) => (list:T[]):{[id:string]:T} => list.reduce(
  (map, item) => {
    const identifier = castArray(get<T, T[K]|T[K][]>(item, props)).join('');
    map[identifier] = item;
    return map;
  },
  {}
);

What the function does is not important for my issue. It's all about the first part of the signature <T, K extends keyof T>. I rather would only write <T>. Because then it would be easier to call the function.

I already defined an interface which is exactly what I want, but how do I add the implementation?

interface NormalizerFactory<T extends {}> {
  <K extends keyof T>(...props:K[]):(list:T[]) => {[id:string]:T};
}

Solution

  • You can remove the second generic by replacing K with keyof T, like this:

    const normalizeToProps = <T>(...props:(keyof T)[]) => (list:(keyof T)[]):{[id:string]:T} => list.reduce(
      (map, item) => {
        const identifier = castArray(get<T, T[keyof T]|T[keyof T][]>(item, props)).join('');
        map[identifier] = item;
        return map;
      },
      {}
    );