Home > Software design >  React-Typescript: How to write interface with conditional statement
React-Typescript: How to write interface with conditional statement

Time:11-10

I'm trying to have an interface with a conditional statement.

In an interface, I know we could have something like this below to have the conditional.

interface exampleInterface {
    a: 'A' | 'B'
}

This way, we could ensure the input 'a' must be either 'A' or 'B'. I would like to populate this kind of conditional from an array like ['A', 'B']

Is there a way we can do like this below?

const a_list = Object.keys(config.a_list) // ['A', 'B'] I want to generate this from the config file.
interface exampleInterface {
    a: oneOf(a_list)
}

The reason why I would like to this way is the input array is dynamic(getting information from a config file). Any idea or suggestions helps. Thank you.


Additional Information: I have created the array from the config file and did the below in the interface.

interface myInterface {
    a: typeof a_list[number],
}

But when I tried to get the information from the config file from the user input like this below, I get the following error.

export default function myFunc(props: myInterface)
    const [a] = useState(config.a_config[props.a].map((a) => a))

// Element implicitly has an 'any' type because the expression of type 'string' can't be used to index type.
//  No index signature with a parameter of type 'string' was found on the type.

CodePudding user response:

Perhaps an array of enums

Here is a useful link: https://stackoverflow.com/a/56036508/17364288

enum MyEnum {
    A = 'foo',
    B = 'bar'
}

interface exampleInterface {
    a: MyEnum[]
}

CodePudding user response:

It all depends on the type of config you want to use. To make work type checking, your config must be readable on compile / type-check time, so the first solution is to use JSON file, and import it.

then your task can be converted to two:

File: simple.json as config

{
  "union": ["A", "B", "C"], 
  "x": { "a": 1, "b": 1, "c": 1 }
}

File: importJsonAsConfig.ts requires "resolveJsonModule": true in tsconfig

import configFromJson from "./simple.json";

type abUnionFromJson = keyof typeof configFromJson.x;
//                   = "a" | "b" | "c"

I don't manage to get union work, but the map in JSON works ok.

Then if you have JSON config you, can convert it to js/ts and write config more comfortably;

File: simpleConfig.ts

const config = {
  union: ["A", "B", "C"],
} as const; //ts config needed for this as const
export default config;

File: importJsonAsConfig.ts

import tsConfig from "./simpleConfig";
type ABTulupeFromTs = typeof tsConfig.union;
type AB = ABTulupeFromTs[number];
//      = "A" | "B" | "C"

so maybe you just need type AB = "A" | "B" in your ts config file. :)

  • Related