1

I am calling a function using an "options object" but I would like to be more DRY. Currently, using a contrived example, I do this:

// "options" being the options object
function refineMacroData(options: {file1: string, file2: string, file3: string, file4: string}) {
  // Do the stuff
}

// file2 and file3 arguments are the same in both branches for this context
if (isThisTrue()) {
  refineMacroData({
    file1: 'if this is true',
    file2: 'usually the same',
    file3: 'also usually the same',
    file4: 'also if this is true'
  })
} else {
  refineMacroData({
    file1: 'if this is false',
    file2: 'usually the same',
    file3: 'also usually the same',
    file4: 'also if this is false'
  })
}

What would be nicer is if I could, hypothetically, do

// Same function as before
function refineMacroData(options: {file1: string, file2: string, file3: string, file4: string}) {
  // Do the stuff
}

const commonParams=  {file2: 'usually the same', file3: 'also usually the same'}

if (isThisTrue()) {
  refineMacroData({file1: 'something', commonParams, file4: 'another one again'})
} else {
  refineMacroData({file1: 'different', commonParams, file4: 'different again'})
}

However, the Typscript compiler says

TS2345: Argument of type '{ file1: string; params: { file2: string; file3: string; }; file4: string; }' is not assignable to parameter of type '{ file1: string; file2: string; file3: string; file4: string; }'.   Object literal may only specify known properties, and 'params' does not exist in type '{ file1: string; file2: string; file3: string; file4: string; }'.

I get that this is not, technically, the same type but it looks like it should "fit" in there. Is there a way to "explode" the commonParams map so it can be inserted into the arguments? Thereby avoiding duplication.

Friedrich 'Fred' Clausen
  • 3,321
  • 8
  • 39
  • 70

1 Answers1

1

Yes, what you're calling "exploding" is known in JavaScript (and TypeScript) as spreading, which can be achieved via spread syntax (...), as follows:

if (isThisTrue()) {
  refineMacroData({ file1: 'something', ...commonParams, file4: 'another one again' })
} else {
  refineMacroData({ file1: 'different', ...commonParams, file4: 'different again' })
}

Playground link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360