Home > database >  Typescript keyof generic condition
Typescript keyof generic condition

Time:08-28

Is it possible to make the type property depend on the value of name? I tired this, but it doesn't work:

type Attribute<T> = {
  name: keyof T;
  type: T[keyof T] extends string ? 'a' : 'b';
};

type Item = {
  id: string;
  date: number;
};

const att1: Attribute<Item> = {
  name: 'id',
  type: 'a', // this should work
};

const att2: Attribute<Item> = {
  name: 'id',
  type: 'b', // this should not work
};

const att3: Attribute<Item> = {
  name: 'date',
  type: 'b', // this should work
};

CodePudding user response:

The problem is that T[keyof T] extends string is expanded to all types that T[keyof T] can assume, and at least one of them doesn't extend string, so the condition is always false.

One solution is to use a mapped type to produce an object type whose values are all the allowed types, then index that with keyof T again to get a union of the individual types out:

type Attribute<T> = {
  [K in keyof T]: {
    name: K,
    type: T[K] extends string ? 'a' : 'b';
  }
}[keyof T]

I'm not sure this is the simplest solution, but it does seem to work.

  • Related