typescript - Kuinka välittää valinnaisia parametreja jättäen toisia valinnaisia parametreja pois?


Kun otetaan seuraava allekirjoitus:

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

Kuinka voin kutsua funktiota error() ilman että määritän title-parametrin, mutta asettamalla autoHideAfter-arvoksi esimerkiksi 1000?

Vastaus #1

Kuten dokumentaatiossa on määritelty, käytä 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);

Leikkikentän linkki.

Vastaus #2

Valitettavasti TypeScriptissä ei ole mitään tällaista (lisätietoja täällä: https://github.com/Microsoft/TypeScript/issues/467)

Mutta tämän kiertämiseksi voit muuttaa parametrit rajapinnaksi:

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

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

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

Vastaus #3

Toinen lähestymistapa on:

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

Joten kun haluat jättää otsikkoparametrin pois, lähetä tiedot vain näin:

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

Pidän mieluummin tästä vaihtoehdosta, koska se sallii minun lisätä lisää parametreja ilman, että minun tarvitsee lähettää muita.

Voit myös käyttää Partial<T>-tarkennetta metodin allekirjoituksessa, mutta tässä tapauksessa sinun täytyy luoda rajapinta vaihtoehdoillesi:

interface IMyOptions {
  title: string;
  autoHideAfter: number;
}

Ja sitten metodin allekirjoitus voi näyttää tältä:

error(message: string, options?: Partial<IMyOptions>);

Käyttö on sama kuin yllä.

Tyyppi Partial<T> tulisi olla jo määritelty globaaleissa tyyppitiedostoissa seuraavasti:

type Partial<T> = {
  [P in keyof T]?: T[P];
};

Vastaus #4

voit käyttää valinnaista muuttujaa ? avulla tai jos sinulla on useita valinnaisia muuttujia, voit käyttää ..., esimerkki:

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

Yllä:

  • name on pakollinen
  • country on pakollinen ja sillä on oletusarvo
  • osoite on valinnainen
  • hobbies on taulukko valinnaisista parametreista

Vastaus #5

Tämä on melkein sama kuin @Brocco:n vastaus, mutta pienen käänteen kanssa: välitä valinnaiset parametrit vain objektissa. (Ja tee myös params-objekti valinnaiseksi).

Se päätyy olemaan eräänlainen kuin Pythonin **kwargs, mutta ei aivan.

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

Aiheeseen liittyviä artikkeleita