Home > database >  Infer typescript function generic from param value
Infer typescript function generic from param value

Time:11-24

I have the following function:

enum EventType {
  First = 'first',
  Second = 'second',
}

type First = {
  first: string;
  type: EventType.First;
};
 
type Second = {
  second: string;
  type: EventType.Second;
};

type Data = First | Second;

interface Options<T extends EventType = EventType> {
  matcher: (data: Extract<Data, { type: T }>) => boolean;
  type: T;
}

function foo(options: Options) {
  ...
}

I'm trying to achieve strict types on the matcher functions data param based on the value of type. For example with this usage:

foo({
  matcher: data => ..., // data has type First
  type: EventType.First,
});

foo({
  matcher: data => ..., // data has type Second
  type: EventType.Second,
});

My code doesn't achieve this, I think because it isn't clear where the generic T takes it's value. Is it possible to do what I want?

CodePudding user response:

foo must be made generic in order to allow Options to correctly infer the type:

enum EventType {
  First = 'first',
  Second = 'second',
}

type First = {
  first: string;
  type: EventType.First;
};
 
type Second = {
  second: string;
  type: EventType.Second;
};

type Data = First | Second;

interface Options<T extends EventType = EventType> {
  matcher: (data: Extract<Data, { type: T }>) => boolean;
  type: T;
}

function foo<E extends EventType>(options: Options<E>) {}

foo({
  matcher: data => true, // data has type First
  type: EventType.First,
});

foo({
  matcher: data => true, // data has type Second
  type: EventType.Second,
});

enter image description here

  • Related