Typescript optional erweiternde Schnittstelle

Lesezeit: 5 Minuten

Benutzeravatar von Louie Bertoncin
Louie Bertoncin

ich habe zwei interfaces, von denen einer den anderen verlängert. Allerdings würde ich gerne den ersten verlängern können interface und machen Sie alle seine Typen optional. Ich möchte nicht alle Definitionen der ersten umschreiben müssen interface in meinem zweiten optional sein interface (denn was ist der Vorteil, an diesem Punkt zu erweitern?) oder den ersten neu definieren interface weil es woanders verwendet wird.

Wie es aussieht:

interface First {
  type1: string
  type2: string
}

// Seemingly pointless rewrite (why would I even need to extend?)
interface Second extends First {
  type1?: string
  type2?: string
  type3: string
  type4: string
}

// What I imagine the extending should be (but doesn't work)
interface Second extends First? {
  type3: string
  type4: string
}

Ich habe meine Nachforschungen angestellt und diese Frage gefunden, die etwas sehr Ähnliches beantwortet, aber es ist ein Jahr her, seit diese Frage berührt wurde, und ich denke, mein Problem ist nicht genau das gleiche, weil ich das machen möchte gesamte erweitert interface optional, nicht nur ein paar Typen davon.

Gibt es eine Möglichkeit, dies in Typescript zu tun, oder muss ich es nur aufsaugen und eine lange Sekunde machen interface?


Update (um zu erklären, warum ich diese Arbeit haben möchte):

Ich schreibe eine React-Web-App und habe eine Komponente, die eine Entität aus meiner Datenbank so anzeigt, dass der Benutzer jeden Wert dieser Entität bearbeiten kann. Ich möchte, dass meine React-Komponente den Fall behandelt, in dem der Benutzer eine neue Entität erstellt, sowie den Fall, in dem der Benutzer eine vorhandene Entität bearbeitet.

Um bei meinem obigen Beispiel zu bleiben, nehmen wir an, dass die Werte meiner Datenbankentität von repliziert werden Zuerst interface und die React-Komponente verwendet zwei übergebene Requisiten, die in der vorhanden sind Zweite interface. Die React-Komponente wird stets haben die beiden Werte in der Zweiteaber nicht unbedingt die Werte von haben Zuerst.

Für den Fall, dass der Benutzer eine neue Entität erstellt, möchte ich die React-Komponente nur mit den Werten von konstruieren Zweiteohne angeben zu müssen null Werte für alles in Zuerst. Im Fall, dass der Benutzer eine vorhandene Entität bearbeitet, würde ich alles ausgeben Zuerst und Zweite.

In beiden Fällen wäre es dieselbe Benutzeroberfläche, die jedoch mit unterschiedlichen Werten erstellt wurde.

  • was ist das Szenario in Ihrem Fall. Update to post hilft Ihnen weiter

    – Aravind

    21. Mai 2017 um 20:38 Uhr

Sie können verwenden Geben Sie Aliase ein zusammen mit einem Überschneidung auf der Teilweise Typ:

type First = {
    type1: string;
    type2: string;
}

type Second = Partial<First> & {
    type3: string;
    type4: string;
}

  • Du bist ein Geschenk des Himmels. Das hat es für mich getan. In all der Zeit, in der ich DefinitelyTyped verwendet habe, ist mir der Typ aus Unwissenheit nicht aufgefallen type und umgesetzt haben interface überall in meinen Projekten.

    – Louie Bertoncin

    21. Mai 2017 um 21:04 Uhr

  • Sie sind in vielen Fällen ziemlich gleich. Unbedingt lesen Schnittstellen vs. Typaliase um besser zu verstehen, wie sie sich unterscheiden.

    – Nitzan Tomer

    21. Mai 2017 um 21:07 Uhr

  • Jetzt, wo ich weniger jung und naiv bin, sehe ich das interface Second extends Partial<First> funktioniert genauso gut (wie in Dibyos Antwort unten gezeigt)

    – Louie Bertoncin

    1. August 2020 um 1:02 Uhr

Benutzeravatar von Dibyo Majumdar
Dibyo Majumdar

Sie können dies mit Schnittstellen tun, indem Sie die verwenden Partial Typ.

interface First {
    type1: string;
    type2: string;
}

interface Second extends Partial<First> {
    type3: string;
    type4: string;
}

  • Diese Antwort funktioniert ab TypeScript Version 2.2

    – Luiscla27

    10. Dezember 2021 um 2:25 Uhr


Es gibt eine bessere/einfachere Methode. Verwenden Auslassen Sie können nur die spezifischen benannten Eigenschaften neu definieren.

interface First {
    type1: string;
    type2: string;
}

interface Second extends Omit<First, "type1"> {
    type1?: string;
}

  • Oder in diesem Fall können Sie sogar verwenden Pict<First, "type2"> Anstatt von Omit das Ergebnis wird das gleiche sein

    – Jakub Kurdziel

    15. April um 11:55 Uhr

Sie können auch alle Teile optional machen, indem Sie eine ansonsten leere Schnittstelle bereitstellen:

export interface ISingleScope {
   scope: string;
}

export interface IMultiScope {
   scopes: string[];
   check?: boolean;
}

export interface IProvidedScope 
   extends Partial<ISingleScope>, Partial<IMultiScope> { 
}

Dies erfordert jedoch normalerweise einen expliziten Test der verwendeten Eigenschaft, da zur Laufzeit keine dieser Informationen vorhanden ist. Also, wenn Ihr Objekt mit dem Namen kommt Optionen dann würde das reichen:

if (options && options.scopes) {
   // access properly 'IMultiScope'
}

Extends im Typoskript interface bedeutet, dass das zweite Objekt das erbt, was auch immer das erste Objekt hat, wenn die Eigenschaften des ersten optional sind oder nicht, werden sie ohne Änderungen auf das zweite Objekt angewendet. Sie können dieses Verhalten in Typescript nicht ändern. Die Antwort auf Ihre Frage sollten Sie nicht verwenden extends für deinen Fall.

  • Haben Sie zufällig einen Vorschlag für eine andere Vorgehensweise? Das habe ich schon hergeleitet extends ist der falsche Ansatz, weshalb ich die Frage hier gestellt habe.

    – Louie Bertoncin

    21. Mai 2017 um 20:47 Uhr

  • Die einzige Möglichkeit, das zu implementieren, was Sie möchten, besteht darin, die erste Schnittstelle als optionale Eigenschaft in das zweite Objekt einzufügen. Ich bin mir nicht sicher, ob dies für Sie funktionieren würde.

    – LOB

    21. Mai 2017 um 20:49 Uhr

  • Aber das würde nisten Zuerst innerhalb einer optionalen Eigenschaft, anstatt alle zu haben Zuerst Eigenschaften auf der Stammebene von Zweite, Rechts? Es würde funktionieren, wenn das der Fall wäre, aber es wäre etwas umständlicher.

    – Louie Bertoncin

    21. Mai 2017 um 20:54 Uhr

  • Das ist richtig, aber wie ich Ihnen bereits gesagt habe, machen Sie entweder die Eigenschaften der ersten Schnittstelle optional oder deklarieren Sie sie separat in der zweiten.

    – LOB

    21. Mai 2017 um 20:56 Uhr

  • Haben Sie zufällig einen Vorschlag für eine andere Vorgehensweise? Das habe ich schon hergeleitet extends ist der falsche Ansatz, weshalb ich die Frage hier gestellt habe.

    – Louie Bertoncin

    21. Mai 2017 um 20:47 Uhr

  • Die einzige Möglichkeit, das zu implementieren, was Sie möchten, besteht darin, die erste Schnittstelle als optionale Eigenschaft in das zweite Objekt einzufügen. Ich bin mir nicht sicher, ob dies für Sie funktionieren würde.

    – LOB

    21. Mai 2017 um 20:49 Uhr

  • Aber das würde nisten Zuerst innerhalb einer optionalen Eigenschaft, anstatt alle zu haben Zuerst Eigenschaften auf der Stammebene von Zweite, Rechts? Es würde funktionieren, wenn das der Fall wäre, aber es wäre etwas umständlicher.

    – Louie Bertoncin

    21. Mai 2017 um 20:54 Uhr

  • Das ist richtig, aber wie ich Ihnen bereits gesagt habe, machen Sie entweder die Eigenschaften der ersten Schnittstelle optional oder deklarieren Sie sie separat in der zweiten.

    – LOB

    21. Mai 2017 um 20:56 Uhr

1430810cookie-checkTypescript optional erweiternde Schnittstelle

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy