TypeScript lässt Sie den Typ einer markierten Union nicht automatisch nachschlagen. Es ist eine nette Idee, also möchten Sie vielleicht make a suggestion. Die Logik ist bereits im Rahmen der Kontrollflussanalyse implementiert; vielleicht könnte es als ein Typ-Operator irgendeiner Art entlarvt werden.
In Ermangelung dieser Funktion gibt es Workarounds. Der einfachste Weg ist, genau das Gegenteil zu erklären, selbst abbildet und dann darauf zu verweisen, wenn Sie es brauchen, auf Kosten einiger Wiederholung:
type ActionMapping = {
ADD_TODO: AddTodoAction;
REMOVE_TODO: RemoveTodoAction;
}
interface Action { type: keyof ActionMapping }; // useful for consistency
interface AddTodoAction extends Action {
type: 'ADD_TODO'; // manually cross-reference
description: string;
}
interface RemoveTodoAction extends Action {
type: 'REMOVE_TODO'; // manually cross-reference
id: number;
}
// if you want more Action types you need to add it to ActionMapping:
interface BadAction extends Action {
type: 'BAD'; // error, BadAction incorrectly extends Action
title: string;
}
Jetzt können Sie definieren, was Sie wollen als:
type ActionReducers = {
[P in keyof ActionMapping]: (state: State, action: ActionMapping[P]) => State
};
Hier ist eine andere Art und Weise mit weniger Vervielfältigung, aber das ist mehr verworren:
// define all your data types here without the type property
type ActionDataMapping = {
ADD_TODO: { description: string },
REMOVE_TODO: { id: number }
}
// the ActionMapping programmatically adds the right tag to the data
type ActionMapping = {
[K in keyof ActionDataMapping]: ActionDataMapping[K] & { type: K };
}
// and an Action is just the union of values of ActionMapping properties
type Action = ActionMapping[keyof ActionMapping];
// this is the same as above
type ActionReducers = {
[P in keyof ActionMapping]: (state: State, action: ActionMapping[P]) => State
};
Hier sollte auch alles funktionieren. Ihnen fehlen schöne Namen für Ihre Action
Subtypen. Fügen Sie sie zurück, wenn Sie wollen, aber es ist ein wenig mehr Duplizierung:
// if you need names for them:
type AddTodoAction = ActionMapping['ADD_TODO'];
type RemoveTodoAction = ActionMapping['REMOVE_TODO'];
Hoffnung eines jener Werke für Sie. Viel Glück!
ich glaube, die nächste Sie auf das gewünschte Verhalten zu bekommen, ist typeguards ein Reduktions wie dies ohne Fehler kompiliert werden: '(Stand: Staat, Aktion: Aktion) => { Schalter (action.type) { Fall 'ADD_TODO': action.description; Rückkehrzustand; Fall 'REMOVE_TODO': action.id; Rückkehrzustand; } } ' hmpf Ich vermisse echte Code-Formatierung in Kommentaren – Kalle