Home > Mobile >  Typescript String enum type 'string' is not assignable to type
Typescript String enum type 'string' is not assignable to type

Time:10-06

Link to Playground

Pretty simple, how do I avoid this compile error?

type ExampleClass = {
    relevantValue: EXAMPLE_STRING_ENUM;
}

enum EXAMPLE_STRING_ENUM {
    HELLO = 'hello',
}

const exampleArray: ExampleClass[] = [];

const mockData = {
    relevantValue: 'hello'
}

exampleArray.push(mockData);

results in

Argument of type '{ relevantValue: string; }' is not assignable to parameter of type 'ExampleClass'. Types of property 'relevantValue' are incompatible. Type 'string' is not assignable to type 'EXAMPLE_STRING_ENUM'.(2345)

In my head this should work. During writing code, I can have a switch/case statement depending on what a given field is, but the mockData comes from live, so of course it is not having an enum value, but directly the string value instead.
I thought since it is a string enum, typescript should know that the values can only be of type string?
I could just fix it by making a union type like this:

type ExampleClass = {
    relevantValue: EXAMPLE_STRING_ENUM | string;
}

but this does not really solve the underlying problem, which I am still trying to fix.
Also, this 'fix' would lead to follow up errors like such:

exampleArray.forEach((e) => {
setFoo(e.relevantValue)
})

Argument of type 'string' is not assignable to parameter of type 'SetStateAction<EXAMPLE_STRING_ENUM | undefined>'.(2345)

EDIT: Solved it, by typing all values where the compiler cannot know whether the string provided really is matching one of the ENUM strings, so throwing the error made sense. Updated code:

const [foo, setFoo] = React.useState<EXAMPLE_STRING_ENUM>();


type ExampleClass = {
    relevantValue: string;
}

enum EXAMPLE_STRING_ENUM {
    HELLO = 'hello',
}

const exampleArray: ExampleClass[] = [];

const mockData: ExampleClass = {
    relevantValue: 'hello'
}

exampleArray.forEach((e) => {
setFoo(e.relevantValue as EXAMPLE_STRING_ENUM)
})

CodePudding user response:

You need to add a guard to the mockData constant to let Typescript know that relevantValue is constrained to values in the enum:

const mockData: ExampleClass = {
    relevantValue: EXAMPLE_STRING_ENUM.HELLO
}

If you don't do this then the following is allowed, which is why typescript errors in your example:

mockData.relevantValue = 'not an enum value';

playground

  • Related