Come passare parametri opzionali mentre si omettono alcuni altri parametri opzionali?


282

Data la seguente firma:

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

Come posso chiamare la funzione error() non specificando il titleparametro, ma impostando autoHideAfterper dire 1000?

Risposte:


307

Come specificato nella documentazione , utilizzare 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);

Link al parco giochi .


6
@ BBi7 Penso che tu abbia frainteso la documentazione. Il valore ?viene aggiunto nella definizione della funzione , ma la domanda riguarda l'effettiva chiamata della funzione.
Thomas,

Ciao @Thomas Capisco perfettamente la documentazione e so che devi aggiungere il? dopo il parametro nella definizione della funzione. Ma, in relazione alla chiamata di una funzione con parametri opzionali, suppongo che il passaggio sia indefinito se non applicabile. In genere cerco di trovare il modo di rendere i parametri opzionali come parametri finali, quindi non posso semplicemente passare contro indefiniti. Ma ovviamente se ne hai molti, allora dovresti passare indefinito o qualcosa di non vero. Non sono sicuro di cosa mi riferissi quando ho pubblicato inizialmente. Significato Non so se è stato modificato, ma quello che vedo ora è corretto.
BBi7,

2
@ BBi7 Non ci sono state modifiche recenti. Ok, non importa allora :) (Nota che in realtà devi passare undefinedper ottenere lo stesso comportamento di tralasciare completamente l'argomento. Solo "qualsiasi cosa non veritiera" non funzionerà, perché TypeScript in realtà confronta con void 0quale è un modo più sicuro di scrivere undefined. )
Thomas,

71

Sfortunatamente non c'è nulla di simile in TypeScript (maggiori dettagli qui: https://github.com/Microsoft/TypeScript/issues/467 )

Ma per ovviare a questo puoi modificare i tuoi parametri in modo che siano un'interfaccia:

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

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

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

Potresti dirlo, posso chiamare il metodo dell'errore come questo, errore ({message: 'test'}), penso, non possiamo, quindi errore ({message: 'test', autoHideAFter: undefined}), ma quello che mi aspetto è un errore (messaggio), se non ho superato altri parametri, si prenderanno i valori dai parametri predefiniti.
Cegone,

37

puoi usare la variabile opzionale da ?o se hai più variabili opzionali da ..., ad esempio:

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

In quanto sopra:

  • name è obbligatorio
  • country è obbligatorio e ha un valore predefinito
  • address è facoltativo
  • hobbies è una matrice di parametri opzionali

2
Gli hobby non dovrebbero essere digitati come array?
Programmatore dal

4
Ci sono informazioni utili in questa risposta, ma non risponde alla domanda. La domanda è, come la vedo io, come si possono bypassare / saltare diversi parametri opzionali e impostare solo quelli specifici.
MaxB,

2
Paese non è richiesto, è un parametro facoltativo con un valore predefinito "CA" anziché non definito. se è necessario, qual è il punto di fornire valore predefinito?
Anand Bhushan,

19

Un altro approccio è:

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

Quindi, quando si desidera omettere il parametro title, basta inviare i dati in questo modo:

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

Preferirei questa opzione perché mi consente di aggiungere più parametri senza dover inviare gli altri.


Come passeresti anche un valore predefinito a title?
Dan Dascalescu il

13

È quasi la stessa della risposta di @Brocco, ma con una leggera svolta: passa solo parametri opzionali in un oggetto.(E anche rendere l'oggetto params opzionale).

Finisce per essere un po 'come i kwargs di Python, ma non esattamente.

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

È possibile specificare più firme di metodo sull'interfaccia quindi avere più overload di metodi sul metodo di classe:

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
    }
}

Ora tutti questi funzioneranno:

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);

... e il errormetodo di INotificationServiceavrà le seguenti opzioni:

Sovraccarico di intellisense

Terreno di gioco


9
Solo una nota che raccomanderei contro questo e invece passare un oggetto e mettere questi parametri come proprietà su quell'oggetto ... è molto meno lavoro e il codice sarà più leggibile.
David Sherret,

2

È possibile creare un metodo helper che accetta una base di parametri di un oggetto su argomenti di errore

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

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

-1

Potresti provare a impostare il titolo su null.

Questo ha funzionato per me.

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

3
Questo funzionerà dal momento che se il parametro della funzione ha un valore predefinito quando si invia null a quel parametro della funzione non verrà impostato sul valore predefinito
Okan SARICA

-2

Puoi farlo senza un'interfaccia.

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

usa l' ?operatore come parametro opzionale.


ma questo non ti consente in alcun modo di specificare messageeautoHideAfter
Simon_Weaver,

3
non rispondi alla domanda o non l'hai letta. Vuole sapere come chiamare un metodo con più parametri opzionali, senza dover specificare il primo opzionale se vuole solo inserire il secondo.
Gregfr,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.