Typoskript Spielplatz

Ich möchte die string -Eigenschaften aus SOME_OBJECT extrahieren und als Union-Typ abrufen. Daher erwarte ich im folgenden Beispiel, dass STRING_KEYS vom Typ "title" | "label" ist.

interface SOME_OBJECT {
    title:      string,
    label:      string,
    someBool:   boolean,
    someDate:   Date,
    someNumber: number
}

type ExtractString<T> = keyof T extends string ? keyof T : never;

type STRING_KEYS = ExtractString<SOME_OBJECT>  // <----- THIS SHOULD BE "title" | "label"

Das bekomme ich:

enter image description here

Ich denke, ich bin hier in der richtigen Richtung (indem ich bedingte Typen verwende), aber dort bin ich noch nicht ruhig. Was ist der beste Weg, um dies zu erreichen?

1
cbdeveloper 6 Okt. 2020 im 18:47

2 Antworten

Beste Antwort

Die Idee aus dem folgenden Beispiel stammt von Typescript Docs: Distributive Bedingte Typen

enter image description here

Also habe ich es angepasst und es funktioniert:

interface SOME_OBJECT {
    title:      string,
    label:      string,
    someBool:   boolean,
    someDate:   Date,
    someNumber: number
}

type ExtractStringPropertyNames<T> = {
    [K in keyof T]: T[K] extends string ? K : never
}[keyof T]

type STRING_KEYS = ExtractStringPropertyNames<SOME_OBJECT>

enter image description here

Typoskript Spielplatz

Wenn möglich, bin ich immer noch daran interessiert, andere Möglichkeiten zu finden. Vor allem, wenn es einfachere Möglichkeiten gibt, da ich denke, dass sich diese Antwort wie ein "Hack" anfühlt, weil sie nicht sehr klar macht, was der Code tut.


UPDATE (WIE ES FUNKTIONIERT)

Ich habe ein bisschen mehr studiert, um zu verstehen, was der Code tatsächlich tut, und ich denke, ich habe es herausgefunden.

Ich habe es in zwei Schritte unterteilt:

SCHRITT 1

Im ersten Schritt wird ein neues Objekt / Typ erstellt.

Die Schlüssel für dieses neue Objekt haben dieselben Schlüssel K in keyof T wie die Schlüssel des generischen Typs T (im Beispiel SOME_OBJECT).

Und für die Werte dieser Schlüssel prüfen wir den generischen Typ T, ob die Werte für diese Eigenschaften K string erweitern. Dies bedeutet, dass diese Werte string zugewiesen werden können. Beispiel: string, "some_hard_coded_string_type" und any bestehen den Test.

Für jede Eigenschaft, die den Test besteht, wiederholen wir ihren Schlüsselnamen K als Wert für sie, andernfalls bestehen wir never. Sie können das Ergebnis in STEP_1_RESULT unten sehen.

enter image description here

SCHRITT 2

In diesem Schritt wird das Objekt einfach aus dem Schritt 1 generiert und gefragt Typoskript, um alle möglichen Werte zurückzugeben, indem Sie type STEP_2<T> = T[keyof T] ausführen.

Denken Sie daran, dass keyof T die Vereinigung aller Eigenschaften von T darstellt. Typescript gibt also eine Union mit allen möglichen Werten für das STEP_1_RESULT Objekt zurück, wenn es mit den Mitgliedern der keyof T Union aufgerufen wird.

In unserem Beispiel wird "title" | "label" | never | never | never zurückgegeben.

Da die never -Typen innerhalb eines Union-Typs bedeutungslos sind, werden diese Werte verworfen und es bleibt "title" | "label".

enter image description here

3
cbdeveloper 7 Okt. 2020 im 07:48

Ich bin mir über die bedingten Typen nicht wirklich sicher. Was ich hier wahrscheinlich versuchen würde, ist die Auswahl und ich würde so etwas machen

interface SOME_OBJECT {
    title:      string,
    label:      string,
    someBool:   boolean,
    someDate:   Date,
    someNumber: number
}

type ExtractString = Pick<SOME_OBJECT, "title" | "label">;

type STRING_KEYS = ExtractString
0
Dharman 6 Okt. 2020 im 16:11