2

If we have a function like this:

function foo(param1: string, param2: number);

and an object like this:

let obj = {param1: 'blah', param2; 10}

How can I directly unwrap the object to pass its data to the function arguments? Something like this:

foo(...obj)
Anmol Singh Jaggi
  • 8,376
  • 4
  • 36
  • 77

2 Answers2

3

You can use Object.values to get the values of an object. The problem is that the order is not necessarily guaranteed and so this would be extremely error prone since order matters usually in function parameters:

Object.values({param1: 'blah', param2: 10}) // ["blah", 10]

Object.values({param2: 10, param1: 'blah'}) // [10, "blah"]

So for example in JS this would work:

function foo(param1: string, param2: string) { console.log(param1, param2)}

let obj = { param1: 'blah', param2: "10" }
foo(...Object.values(obj));

TS does not allow the above because it can't be sure that what values returned will have two items, so the only place this would be allowed and advisable is if you have a rest parameter:

declare function foo(...param1: string[]): void;

let obj = { param1: 'blah', param2: "10" }
foo(...Object.values(obj));

You can create a function to extract the object values into a tuple and spread that to the values, but at that point you are probably better off ust using regular syntax. I present this version below mostly for some fun with tuple types :

declare function foo<T>(param1: string, param2: number): void;
function args<T, K extends (keyof T)[]>(o: T, ...keys:K) : { [P in keyof K]: K[P] extends keyof T ? T[K[P]]: never} {
    let r : any[] = []
    for (const key of keys) {
      r.push(o[key]);
    }
    return r as any;
}

let obj = { param1: 'blah', param2: 10 }
foo(...args(obj, 'param1', 'param2'));

NOTE The better solution is to change foo to take in an object instead of separate params.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
3

In addition to @Titian Cernicova Dragomir's answer.

I couldn't find any convention of doing this.

What you can do (as it is also suggested by @Titian Cernicova Dragomir) is :

let obj = {param1: 'blah', param2; 10}
function foo({param1: string, param2: number}){}

foo(obj);

or you can also make manual deconstruction

let obj = {param1: 'blah', param2; 10}
function foo({param1: string, param2: number}){}


let {param1, param2} = obj;
foo(obj);
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72