Reputation: 48
I have a type with key-value pairs, where keys are React component names and values are the values they take as props. What I am trying to do is to type an array of types containing the type field, which is also the exact name of a component, and a getter
and setter
functions that use component values types.
type ElementValues = {
text: string,
checkbox: boolean
}
type ElementType = keyof ElementValues
type Value<Type extends ElementType> = ElementValues[Type]
type Test = {
[Type in ElementType]: {
type: Type
getter: () => Value<Type>
setter: (value: Value<Type>) => any
}}[ElementType]
const testList: Array<Test> = [{
type: 'checkbox',
getter: () => 'test,
setter: (value) => ({ })
}]
What I can get is the array with elements that do not care about the given component name and take all possible component value types as setter and getter params/return types.
In the above example, getter
should require boolean
, as for checkbox value, and setter
should have a value type of boolean
, not boolean | string
.
Upvotes: 0
Views: 2402
Reputation: 48
It seems that adding helper type Elements
solved the problem.
Based on @lepsch answer:
type ElementValues = {
text: string,
checkbox: boolean
}
type ElementType = keyof ElementValues
type Value<Type extends ElementType> = ElementValues[Type]
type Test<Type extends ElementType> = {
type: Type
getter: () => Value<Type>
setter: (value: Value<Type>) => any
}
type Elements = {
[Type in ElementType]: Test<Type>
}[ElementType]
const testList: Array<Elements> = [
{
type: 'text',
getter: () => 'test',
setter: (value) => ({ })
},
{
type: 'checkbox',
getter: () => true,
setter: (value) => ({ })
}
]
Upvotes: 0
Reputation: 10319
The following would do the trick. Just use discriminated unions. This way the array elements are going to be discriminated by the type
field (text
or checkbox
).
type ElementValues = {
text: string,
checkbox: boolean
}
type ElementType = keyof ElementValues
type Value<Type extends ElementType> = ElementValues[Type]
type Test<Type extends ElementType> = {
type: Type
getter: () => Value<Type>
setter: (value: Value<Type>) => any
}
// Here - Discriminated Unions
type Elements =
| Test<'checkbox'>
| Test<'text'>
const testList: Array<Elements> = [
{
type: 'text',
getter: () => 'test1',
setter: (value) => ({ })
},
{
type: 'checkbox',
getter: () => true,
setter: (value) => ({ })
}
]
Upvotes: 1