0

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.

2 Answers 2

1

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) => ({ })
  }
]
Sign up to request clarification or add additional context in comments.

6 Comments

How is this different to the code in the question?
I've edited the answer to point exactly where the most important change is as a comment in the code itself.
I see that the code is a bit different. But the result looks to be exactly the same.
Oh, I see. It looks like I've just "deobfuscated" it a bit. OP had the answer all the time in his/her own question. (:
He probably is looking for something else, but has trouble telling us exactly what he wants.
|
0

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) => ({ })
  }
]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.