Kan du ha valfria destrukturerade argument i en Typescript-funktion?


Jag skulle vilja skriva en funktion som tar ett objektargument, använder destrukturering i funktionssignaturen, och låter det argumentet vara valfritt:

myFunction({opt1, opt2}?: {opt1?: boolean, opt2?: boolean})

Men Typescript tillåter mig inte ("Ett bindningsmönsterparameter kan inte vara valfritt i en implementation-signatur.").

Självklart skulle jag kunna göra det om jag inte hade destrukturerat:

myFunction(options?: {opt1?: boolean, opt2?: boolean}) {
  const opt1 = options.opt1;
  const opt2 = options.opt1;
  ...

Det verkar som att dessa borde vara samma sak, men det översta exemplet är inte tillåtet.

Jag skulle vilja använda en destrukturerad syntax (1) eftersom den finns och är en trevlig syntax, och det verkar naturligt att de två funktionerna ovan borde fungera på samma sätt, och (2) eftersom jag också vill ha ett kortfattat sätt att ange standardvärden:

myFunction({opt1, opt2 = true}?: {opt1?: boolean, opt2?: boolean})

Utan destrukturering måste jag begrava dessa standardvärden i funktionens implementation, eller ha ett argument som faktiskt är någon klass med en konstruktör...

Svar #1

Använd istället en standardparameter:

function myFunction({ opt1, opt2 = true }: { opt1?: boolean; opt2?: boolean; } = {}) {
    console.log(opt2);
}

myFunction(); // outputs: true

Det är nödvändigt för att inte destrukturera undefined:

function myFunction({ opt1, opt2 }) {
}
    
// Uncaught TypeError: Cannot destructure property `opt1` of 'undefined' or 'null'.
myFunction();

Svar #2

Du kan inte destrukturera om det inte finns ett objekt som anges som argument. Därför använd ett standardobjekt i parametrarna som det tidigare inlägget nämnde:

type Options = { opt1?: boolean; opt2?: boolean; }

function myFunction({ opt1, opt2 }: Options = {}) {
    console.log(opt2, opt1);
}

myFunction() // undefined,  undefined 
myFunction({opt1: false}); // undefined,  false 
myFunction({opt2: true}); // true,  undefined

Det jag skulle vilja tillägga är att detta destruktureringsmönster i parametrarna tillför mest värde när följande två villkor uppfylls:

  • Antalet alternativ kommer troligen att förändras
  • Det kan potentiellt ske en förändring i API:t för funktionen. D.v.s. funktionsparametrarna kommer sannolikt att ändras

I princip ger destrukturering dig mer flexibilitet eftersom du kan lägga till så många alternativ du vill med minimal förändring av funktionens API.

Men den mer grundläggande versionen skulle vara enklare:

// If the function is not likely to change often just keep it basic:
function myFunctionBasic( opt1? :boolean, opt2?: boolean ) {
    console.log(opt2, opt1);
}

Relaterade artiklar