0

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.
2
  • did you use enum? you can define it and then use like type in a prop Commented Nov 9, 2021 at 6:42
  • 1
    Not from config.. Only const a_list = ['A', 'B'] as const and then a: typeof a_list[number] Commented Nov 9, 2021 at 6:48

3 Answers 3

0

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

Comments

0

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. :)

Comments

0

I solved it by just adding as any to config.a_config as below, it might not be the best solution thou.

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

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.