Wyszukiwanie w witrynie

reactjs - Obsługa opcjonalnego pola w Typescript


Poniżej znajduje się mój fragment kodu komponentu React, w którym jedno z pól jest opcjonalne. Ponieważ jest opcjonalne, muszę je zainicjalizować jako undefined, ale to sprawia, że późniejsze jego użycie jest trudne, nawet po sprawdzeniu typu. Nie jestem pewien, jak to rozwiązać. Używam TypeScript w wersji 3.2.2.

interface State {
  open: boolean;
  selected?: SelectedFieldType;
}

class CFilter extends React.Component<Props, State> {
  state = {
    open: false,
    selected: undefined
  };

  onOperatorValueChange = (value: any) => {
    if (typeof this.state.selected !== undefined) {
      console.log(this.state.selected.value); // ERROR: Object is possibly undefined (property): selected undefined
      this.setState({
        selected: {
          ...this.state.selected, // ERROR: Spread types may only be created from object types
          value: value
        }
      });
    }
  };

  render() {
    return (<span>some jsx</span>);
  }
}

Jeśli nie zainicjalizuję selected, wyrzuci mi błąd

Wybrana właściwość nie istnieje

Odpowiedź #1

Nie mam skonfigurowanego Reacta, więc nie mogę tego przetestować, ale moim przypuszczeniem jest, że powinieneś oznaczyć typ state jako State podczas jego inicjalizacji, tak jak

  // note the annotation
  state: State = {
    open: false,
    selected: undefined
  };

zamiast pozwalać kompilatorowi na wywnioskowanie typu. Jest całkiem możliwe, że kompilator uważa, że CFilter['state'] jest węższy niż State (CFilter extends React.Component<Props, State> oznacza, że state może być dowolnym typem, który rozszerza State.) i że CFilter['state']['selected'] jest zawsze undefined. Jeśli tak jest, to this.state.selected zawsze będzie uważane za undefined i niemożliwe jest zmienienie tego za pomocą sprawdzenia null (to niefortunne, że komunikat o błędzie narzeka na możliwość bycia „możliwe” undefined, kiedy uważa, że jest koniecznie undefined, ale tak to jest.)

Spróbuj jawnej adnotacji i zobacz, czy to rozwiąże problem. Mam nadzieję, że to pomoże. Powodzenia!

Odpowiedź #2

Typ 'null' nie może być przypisany do typu 'SelectedFieldType | undefined' brzmi dziwnie... może mógłbyś spróbować dodać tylko do testów pipe pozwalający na wartość null dla SelectedFieldType. Ale to dziwne, że trzeba to robić.

interface State {
  open: boolean;
  selected?: SelectedFieldType | null;
}

Spostrzeżenie od @jcalz również wydaje się bardzo dobre. Powinieneś spróbować.

Jeśli to nie działa, możesz spróbować przepisać swój kod na coś takiego:

class CFilter extends React.Component {
  state: State = {
    open: false,
    selected: null,
  };

  onOperatorValueChange = (value: any) => {
    if (this.state.selected) {
      this.setState({
        selected: { 
          ...this.state.selected,
          value
        }
      });
    }
  };

Przetestowałem to na tym stackblitz i wydaje się działać dobrze, bez żadnych błędów.

Powiązane artykuły