0

I have a component that looks like this:

export interface Props {
  // ... some props
}

export interface State {
  readonly mode: "add" | "delete"
}

export class MyComponent extends Component<Props, State> {
  readonly state = { mode: "add" }
  // ... more component code
}

The problem is this throws the linting error:

Property 'state' in type 'ScannerScreen' is not assignable to the same property in base type 'Component<Props, State, any>'.
  Type '{ mode: string; }' is not assignable to type 'Readonly<State>'.
    Types of property 'mode' are incompatible.
      Type 'string' is not assignable to type '"add" | "delete"'.

Why does TypeScript not recognize that "add" or "delete" are strings or that "add" is one of the allowed types for mode?

J. Hesters
  • 13,117
  • 31
  • 133
  • 249

2 Answers2

1

This is due to type inference -- TypeScript will infer 'add' as string rather than the type 'add'. You can fix this pretty easily by doing: mode: "add" as "add". You can also use a type annotate for the state: readonly state: State = { mode: "add" }.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
0

state is already defined in the base component (as the error mentions).

From the typedefs it is defined as follows:

state: Readonly<S>;

Try

export interface Props {
  // ... some props
}

export interface State {
  readonly mode: "add" | "delete"
}

export class MyComponent extends Component<Props, State> {
  // VSCode will have intellisense for this ...
  this.state = { mode: "add" };
  // ... more component code
}

If you're using VSCode it will even have the correct values in the code hints.

Wainage
  • 4,892
  • 3
  • 12
  • 22