Ich möchte ein typerzwungenes Array von Elementen deklarieren und daraus einen Unionstyp ableiten können. Dieses Muster funktioniert, wenn Sie den Elementen im Array keinen expliziten Typ zuweisen. Ich bin mir nicht sicher, wie ich es am besten erklären soll. Hier ist ein Beispiel:
BEISPIEL 1
type Pair = {
key: string;
value: number;
};
const pairs: ReadonlyArray<Pair> = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']
BEISPIEL 2
type Data = {
name: string;
age: number;
};
const DataRecord: Record<string, Data> = {
foo: { name: 'Mark', age: 35 },
bar: { name: 'Jeff', age: 56 },
} as const;
type Keys = keyof typeof DataRecord;
Hier ist ein Beispiel für das Ableiten der Schlüssel bei der Verwendung as const
. Ich möchte dasselbe Verhalten, aber das Array wird explizit eingegeben.
const pairs = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']; // "foo" | "bar"
gewünschter Wert der Schlüssel: "foo"|"bar"
Istwert der Schlüssel: string
key
Attribut desPair
Typs den gewünschten Typ geben, dann sollte es so funktionieren, wie Sie es geschrieben haben.possibleKeys = ['foo', 'bar'] as const; type Keys = typeof possibleKeys[number]; type Pair = { key: Keys, value: number };
aber Sie müssen die möglichen Schlüssel noch explizit auflisten.Antworten:
Für eine Variable können Sie entweder den Compiler den Typ aus der Initialisierung ableiten lassen oder ihn explizit ausschreiben. Wenn Sie es explizit schreiben, wie Sie es getan haben, wird der Initialisierungswert mit der Annotation verglichen, aber der tatsächliche Typ des Initialisierers hat keinen Einfluss auf den Typ der Variablen (sodass Sie die gewünschten Typinformationen verlieren). Wenn Sie den Compiler darauf schließen lassen, ist es nicht mehr möglich, den Typ so zu beschränken, dass er einer bestimmten Schnittstelle entspricht (wie Sie es zu wollen scheinen).
Die Lösung hierfür besteht darin, eine generische Funktion zu verwenden, um den Wert zu beschränken und auf den tatsächlichen Typ zu schließen:
Spielplatz Link
Hinweis: Für den Array-Fall müssen wir den Compiler ein wenig scharf schalten, um auf String-Literal-Typen für
key
daher das Ganze zu schließen& Array<{key: V}>
, wobeiV
sich ein Typparameter erweitertstring
quelle
Die üblichen Ansätze sind:
pairs
indem Sie den expliziten Typ weglassenReadonlyArray<Pair>
(siehe Antwort ).key
inPair
der Art"foo"|"bar"
Wenn Sie dies nicht möchten, können Sie Ihre Schlüssel nur ableiten und den Typ einschränken , indem Sie
pairs
eine Hilfsfunktion verwenden. DerPair
Typ wird auch generisch gemacht, um die angegebenenkey
String-Literal-Typen zu speichern . Sie können ein IIFE verwenden, um die Zuordnung kompakt zu gestalten:Spielplatz
quelle