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