Website-Suche

Wie implementiert man eine umfassende Switch-Anweisung innerhalb einer Redux-Reducer-Funktion unter Verwendung von Typescript? Wie geht man mit den internen @@redux-Aktionen von Redux um?


Ich habe versucht, eine endgültige Antwort darauf zu finden, aber habe noch keine gefunden.

Es gibt hier auf SO eine Frage, die beantwortet, wie man eine ausführliche switch-Anweisung implementiert:

Wie überprüfe ich, dass ein Switch-Block in TypeScript vollständig ist?

Und die Antwort ist:

Schreiben Sie eine Funktion, die never als Parameter übernimmt, never zurückgibt und beim Aufruf mit beliebigen Werten eine Ausnahme auslöst.

function assertUnreachable(x: never): never {
  throw new Error("Didn't expect to get here");
}

Und verwenden Sie es in Ihrem default-Fall:

switch (action.type) {
  case "A": {
    ...
  }
  case "B": {
    ...
  }
  default: {
    return assertUnreachable(action);  // CAN'T USE action.type HERE BECAUSE action WILL BE never AND action.type WILL BE any
  }
}

Aber ich kann es nicht so innerhalb eines Reducers verwenden. Es wird funktionieren, was die Überprüfung der Vollständigkeit meiner Reducer-Aktionen betrifft, aber zur Laufzeit einen Fehler auslösen, weil Redux es mit seinen eigenen internen Aktionen aufruft, zum Beispiel:

@@redux/INITh.b.0.x.q.h                   // THIS IS THE action.type
@@redux/PROBE_UNKNOWN_ACTIONe.7.b.o.p     // THIS IS THE action.type

Wie ist also der ideale Weg, die Vollständigkeit einer switch-Anweisung innerhalb eines Reducers zu behandeln?

Antwort #1

Die richtige Antwort hier ist, sich darüber überhaupt keine Sorgen zu machen.

Selbst mit dieser Switch-Anweisung wird dein Reducer mit anderen Aktionen aufgerufen. Also hilft es wirklich nicht, die genaue Menge der Aktionen einschränken zu wollen.

Der bessere Ansatz ist es, die createSlice-API aus unserem offiziellen Redux Toolkit-Paket zu verwenden und sie definieren zu lassen, welche Aktionen Sie in diesem speziellen Slice zu bearbeiten erwarten.

Antwort #2

Ich habe eine saubere Lösung in Note zu TypeScripts erschöpfenden Typprüfungen im Rahmen von Reduxs Reducer gefunden. Die Lösung besteht darin:

  • einen Fehler zur Kompilierzeit auslösen
  • werfe keinen Fehler zur Laufzeit
function endReducer<T>(state: T, action: never): T {
    return state;
}

function reducer(state: State, action: Actions) {
    switch (action.type) {
        case ...

        default:
            return endReducer(state, action);
    }
}

Spielplatzlink