typescripttype-definition

How to enable IntelliSense and indexer at the same time in typescript?


For example, I have an object:

const obj = {
  a: (valueA: string) => true;
  b: (valueB: string) => false;
  c: (valueC: string) => false;
};

You see all properties in this object have same type ((value: string) => boolean). Now I want it to have IntelliSense which makes follows possible:

  1. Display a, b, c after I typed obj.;
  2. Limit its type when I try to add a property into obj.

I tried indexer:

const obj: Record<string, ((value: string) => boolean)> = {
  a: (valueA: string) => true;
  b: (valueB: string) => false;
  c: (valueC: string) => false;
};

But now target 1 won't happen, if I don't use indexer, I cannot achieve target 2.


Solution

  • Variable inference is either all or nothing, you either let typescript infer the type or you specify the type yourself.

    You can only do this with a helper function:

    function makeFunctionsMap<T extends Record<string, ((value: string) => boolean)>>(o: T) { return o; }
    const obj = makeFunctionsMap({
      a: (valueA: string) => true,
      b: (valueB: string) => false,
      c: (valueC: string) => false,
    })
    obj.a;
    obj.d // Error
    

    Playground Link

    You can also inline the function if you want to make it shorter and more unreadable (Playground Link)