Wie übergebe ich optionale Parameter, während ich einige andere optionale Parameter weglasse?


282

Gegeben die folgende Unterschrift:

export interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
}

Wie kann ich die Funktion aufrufen, error() ohne den titleParameter anzugeben , sondern um autoHideAfterzu sagen 1000?

Antworten:


307

Verwenden Sie wie in der Dokumentation angegeben undefined:

export interface INotificationService {
    error(message: string, title?: string, autoHideAfter? : number);
}

class X {
    error(message: string, title?: string, autoHideAfter?: number) {
        console.log(message, title, autoHideAfter);
    }
}

new X().error("hi there", undefined, 1000);

Spielplatz Link .


6
@ BBi7 Ich denke du hast die Dokumentation falsch verstanden. Das ?wird in der Funktion hinzugefügt Definition , aber die Frage ist , tatsächlich Aufruf der Funktion.
Thomas

Hallo @Thomas, ich verstehe die Dokumentation total und weiß, dass du die hinzufügen musst? nach dem Parameter in der Funktionsdefinition. Im Zusammenhang mit dem Aufruf einer Funktion mit optionalen Parametern würde ich jedoch davon ausgehen, dass undefiniert übergeben wird, wenn dies nicht zutreffend ist. Im Allgemeinen versuche ich, Wege zu finden, um optionale Parameter als Endparameter festzulegen, damit ich einfach nicht gegen undefiniert übergeben kann. Aber natürlich, wenn Sie viele haben, müssen Sie undefiniert oder etwas nicht Wahres passieren. Ich bin mir nicht sicher, worauf ich mich damals bezog, als ich ursprünglich gepostet habe. Das heißt, ich weiß nicht, ob es bearbeitet wurde, aber was ich jetzt sehe, stimmt.
BBi7

2
@ BBi7 Es wurden keine Änderungen vorgenommen. Okay, dann nie etwas dagegen :) (Beachten Sie, dass Sie tatsächlich passieren muss undefineddas Argument ganz das gleiche Verhalten wie das Weglassen zu bekommen. Einfach „alles nicht-truthy“ wird nicht funktionieren, weil Typoskript tatsächlich im Vergleich zu void 0denen ein sicherer Weg des Schreibens ist undefined. )
Thomas

71

Leider gibt es in TypeScript nichts Vergleichbares (weitere Details hier: https://github.com/Microsoft/TypeScript/issues/467 )

Um dies zu umgehen, können Sie Ihre Parameter so ändern, dass sie eine Schnittstelle darstellen:

export interface IErrorParams {
  message: string;
  title?: string;
  autoHideAfter?: number;
}

export interface INotificationService {
  error(params: IErrorParams);
}

//then to call it:
error({message: 'msg', autoHideAfter: 42});

Könnten Sie bitte sagen, kann ich die Fehlermethode so nennen, Fehler ({message: 'test'}), ich denke, wir können nicht, also error ({message: 'test', autoHideAFter: undefined}), aber Was ich erwarte, ist ein Fehler (Meldung). Wenn ich keine anderen Parameter übergeben habe, sollte es die Werte von den Standardparametern übernehmen.
Cegone

37

Sie können eine optionale Variable von ?oder verwenden, wenn Sie mehrere optionale Variablen von haben ..., zum Beispiel:

function details(name: string, country="CA", address?: string, ...hobbies: string) {
    // ...
}

In obigem:

  • name Wird benötigt
  • country ist erforderlich und hat einen Standardwert
  • address es ist optional
  • hobbies ist ein Array optionaler Parameter

2
Sollten Hobbys nicht als Array eingegeben werden?
ProgrammerPer

4
Diese Antwort enthält nützliche Informationen, die die Frage jedoch nicht beantworten. Die Frage ist, wie ich es sehe, wie man mehrere optionale Parameter umgehen / überspringen und nur bestimmte einstellen kann.
MaxB

2
Land ist nicht erforderlich, es ist ein optionaler Parameter mit dem Standardwert 'CA' anstelle von undefiniert. Wenn dies erforderlich ist, wozu dient dann die Bereitstellung eines Standardwerts?
Anand Bhushan

19

Ein anderer Ansatz ist:

error(message: string, options?: {title?: string, autoHideAfter?: number});

Wenn Sie also den Titelparameter weglassen möchten, senden Sie die Daten einfach wie folgt:

error('the message', { autoHideAfter: 1 })

Ich würde diese Optionen bevorzugen, da ich mehr Parameter hinzufügen kann, ohne die anderen senden zu müssen.


Wie würden Sie auch einen Standardwert übergeben title?
Dan Dascalescu

13

Dies entspricht fast der Antwort von @Brocco, jedoch mit einer leichten Wendung: Übergeben Sie nur optionale Parameter in einem Objekt. (Und machen Sie auch das params-Objekt optional).

Es endet wie Pythons ** kwargs, aber nicht genau.

export interface IErrorParams {
  title?: string;
  autoHideAfter?: number;
}

export interface INotificationService {
  // make params optional so you don't have to pass in an empty object
  // in the case that you don't want any extra params
  error(message: string, params?: IErrorParams);
}

// all of these will work as expected
error('A message with some params but not others:', {autoHideAfter: 42});
error('Another message with some params but not others:', {title: 'StackOverflow'});
error('A message with all params:', {title: 'StackOverflow', autoHideAfter: 42});
error('A message with all params, in a different order:', {autoHideAfter: 42, title: 'StackOverflow'});
error('A message with no params at all:');

5

Sie können mehrere Methodensignaturen auf der Schnittstelle angeben und dann mehrere Methodenüberladungen auf der Klassenmethode haben:

interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
    error(message: string, autoHideAfter: number);
}

class MyNotificationService implements INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
    error(message: string, autoHideAfter?: number);
    error(message: string, param1?: (string|number), param2?: number) {
        var autoHideAfter: number,
            title: string;

        // example of mapping the parameters
        if (param2 != null) {
            autoHideAfter = param2;
            title = <string> param1;
        }
        else if (param1 != null) {
            if (typeof param1 === "string") {
                title = param1;
            }
            else {
                autoHideAfter = param1;
            }
        }

        // use message, autoHideAfter, and title here
    }
}

Jetzt werden alle diese funktionieren:

var service: INotificationService = new MyNotificationService();
service.error("My message");
service.error("My message", 1000);
service.error("My message", "My title");
service.error("My message", "My title", 1000);

... und die errorMethode von INotificationServicehaben die folgenden Optionen:

Intellisense überladen

Spielplatz


9
Nur eine Anmerkung, die ich dagegen empfehlen würde und stattdessen ein Objekt übergeben und diese Parameter als Eigenschaften für dieses Objekt festlegen würde ... es ist viel weniger Arbeit und der Code wird besser lesbar sein.
David Sherret

2

Sie können eine Hilfsmethode erstellen, die einen Ein-Objekt-Parameter basierend auf Fehlerargumenten akzeptiert

 error(message: string, title?: string, autoHideAfter?: number){}

 getError(args: { message: string, title?: string, autoHideAfter?: number }) {
    return error(args.message, args.title, args.autoHideAfter);
 }

-1

Sie könnten versuchen, den Titel auf null zu setzen.

Das hat bei mir funktioniert.

error('This is the ',null,1000)

3
Dies würde nicht funktionieren, da, wenn der Funktionsparameter einen Standardwert hat, wenn Sie null an diesen Funktionsparameter gesendet haben, dieser nicht auf seinen Standardwert gesetzt wird
Okan SARICA

-2

Sie können dies ohne Schnittstelle tun.

class myClass{
  public error(message: string, title?: string, autoHideAfter? : number){
    //....
  }
}

Verwenden Sie den ?Operator als optionalen Parameter.


aber dies erlaubt Ihnen keine Möglichkeit, anzugeben messageundautoHideAfter
Simon_Weaver

3
Sie beantworten die Frage nicht oder haben sie nicht gelesen. Er möchte wissen, wie man eine Methode mit mehreren optionalen Parametern aufruft, ohne die erste Option angeben zu müssen, wenn er nur die zweite eingeben möchte.
Gregfr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.