Search code examples
reactjstypescript-typings

TypeScript Error when Assigning Enum Types to React Component State


I have enums and groups of enums I construct with a type. When I use the groups of enums ( in this case StoneFruit and CitrusFruit ) to type the state of a component, I get a typescript error. But the error message makes absolutely no sense to me

Type Fruits is not assignable to type StoneFruit

TS2416: Property state in type Fruit is not assignable to the same property in base type Component<any, FruitState, any>
Type { one: Fruits; two: Fruits; } is not assignable to type Readonly<FruitState>
Types of property one are incompatible.
Type Fruits is not assignable to type StoneFruit
import React from "react"

enum Fruits {
  Orange,
  Lemon,
  Peach,
  Plum
}

type StoneFruit = Fruits.Peach | Fruits.Plum
type CitrusFruit = Fruits.Orange | Fruits.Lemon

type FruitState = {
  one: StoneFruit
  two: CitrusFruit
}
class Fruit extends React.Component<any, FruitState> {
  state = {
    one: Fruits.Peach,
    two: Fruits.Orange
  }
}

const testState: FruitState = {
  one: Fruits.Peach,
  two: Fruits.Orange
}

if I however place state with the following, there's no more error.

state : FruitState = {
    one: Fruits.Peach,
    two: Fruits.Orange
  }

Solution

  • When you do not explicitly specify a type for a property, TS infers the simplest possible type that these values can fit into, which is Fruits in your case. This is called the best common type mentioned in the document

    In your case:

    state = {
      one: Fruits.Peach,  // TypeScript infers this as Fruits
      two: Fruits.Orange  // TypeScript infers this as Fruits
    }
    

    Then, since TS uses a structural type system, the structure {one: Fruits; two: Fruits;} doesn't fit into FruitState. The solution, as you have already done, is to explicitly the type of state