Home > OS >  Map enum elements to types
Map enum elements to types

Time:04-27

I am trying to have a type per enum value but I don't quite know the syntax to map individual enum element to the type/interface.

Changing value of some parameters require a specific request body and some don't. ParameterOne and ParameterTwo do and ParameterThree doesn't.

enum Parameter {
  ParameterOne = 'ParameterOne',
  ParameterTwo = 'ParameterTwo',
  ParameterThree = 'ParameterThree',
}


interface UpdateParameterOneRequestBody {
  name: string;
  age: number;
}

interface UpdateParameterTwoRequestBody {
  id: string;
  timestamp: number;
  price: number;
}

Final body will always include the following interface plus optionally a specific body from the above.

export interface UpdateParameterRequestBody<T extends Parameter> {
  parameter: T;
  value: boolean;
}

So it may result in UpdateParameterTwoRequestBody & UpdateParameterRequestBody etc. but will always contain the base UpdateParameterRequestBody.

I have tried creating a type and then using it extending the base but it seems I always need to include all the parameters for it to work and I don't want to do that.

type ParameterToRequest = {
  [Parameter.ParameterOne]: UpdateParameterOneRequestBody,
  [Parameter.ParameterTwo]: UpdateParameterTwoRequestBody,
};

type ParameterToRequestBody<T extends Parameter> = 
  UpdateParameterRequestBody<T> & T extends Parameter
    ? ParameterToRequestBodyTypes[T]
    : never;

TS2536: Type 'T' cannot be used to index type 'ParameterToRequestBodyTypes'.

Here's a TypeScript Playground

CodePudding user response:

Does this work for you?

type ParameterToRequestBody<T extends Parameter & keyof ParameterToRequestBodyTypes> = 
  UpdateParameterRequestBody<T> & T extends Parameter
    ? ParameterToRequestBodyTypes[T]
    : never;

I added & keyof ParameterToRequestBodyTypes to the T constraint.

CodePudding user response:

You can fix this using keyof, note that you weren't too far off with what you had:

type P<T extends Parameter> =
  T extends keyof ParameterToRequestBodyTypes
    ? UpdateParameterRequestBody<T> & ParameterToRequestBodyTypes[T]
    : UpdateParameterRequestBody<T>;

type A = P<'foobar'> // compile-time type error
type B = P<Parameter.ParameterOne> // uses UpdateParameterOneRequestBody 
type C = P<Parameter.ParameterTwo> // uses UpdateParameterTwoRequestBody
type D = P<Parameter.ParameterThree> // only UpdateParameterRequestBody

Playground

  • Related