I have a hypothetical api that returns color values based on user selection.
Take an array with string values:
const Input1 = ['red', 'blue', 'purple'];
const Input2 = ['blue', 'white'];
And the api returns objects:
const Response1 = {
red: "#ff0000",
blue: "#0000ff",
purple: "#aa22ff"
}
const Response2 = {
blue: "#0000ff",
white: "#ffffff"
}
I can manually create the types:
type TResponse1 = {
red: string;
blue: string;
purple: string;
}
type TResponse2 = {
blue: string;
white: string;
}
But is it possible to derive the type? Something along the lines of this:
type TGenerated1 = {[any-value-from-Input1: string]: string};
type TGenerated2 = {[any-value-from-Input2: string]: string};
CodePudding user response:
You can convert your arrays into unions and then use those unions as keys in your types:
const Input1 = ['red', 'blue', 'purple'] as const;
const Input2 = ['blue', 'white'] as const;
const Response1: TGenerated1 = {
red: "#ff0000",
blue: "#0000ff",
purple: "#aa22ff"
}
const Response2: TGenerated2 = {
blue: "#0000ff",
white: "#ffffff"
}
type TGenerated1 = { [K in typeof Input1[number]]: string }
type TGenerated2 = { [K in typeof Input2[number]]: string};
CodePudding user response:
A similar approach to the asnwer posted before me.
But I would take the step using the type from the Response1
/Response2
objects inside the record itself like so:
const Input1 = ['red', 'blue', 'purple'] as const;
type Input1Tuple = typeof Input1
const Input2 = ['blue', 'white'] as const;
type Input2Tuple = typeof Input2
const Response1 = {
red: "#ff0000",
blue: "#0000ff",
purple: "#aa22ff"
}
const Response2 = {
blue: "#0000ff",
white: "#ffffff"
}
type TGenerated1 = Record<Input1Tuple[number], typeof Response1[Input1Tuple[number]]>
type TGenerated2 = Record<Input2Tuple[number], typeof Response2[Input2Tuple[number]]>