展开对象以作为函数参数传递

时间:2018-12-21 06:24:06

标签: function typescript types parameter-passing

如果我们有这样的功能:

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

和这样的对象:

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

如何直接解开对象以将其数据传递给函数参数? 像这样:

foo(...obj)

2 个答案:

答案 0 :(得分:2)

除了@Titian Cernicova Dragomir的答案。

我找不到这样做的惯例。

您可以做的(@Titian Cernicova Dragomir也建议这样做)是:

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

foo(obj);

或者您也可以进行手动解构

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


let {param1, param2} = obj;
foo(obj);

答案 1 :(得分:1)

您可以使用Object.values获取对象的值。问题是顺序不一定得到保证,因此这极易出错,因为顺序通常在函数参数中很重要:

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

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

因此,例如在JS中,它将起作用:

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

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

TS不允许上述操作,因为无法确定返回的values是否包含两个项目,因此,如果您有rest参数,则唯一可以允许并建议的地方:

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

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

您可以创建一个函数来将对象值提取到元组中并将其分布到值中,但是到那时,使用常规语法可能会更好。我主要在下面介绍此版本,以了解元组类型的乐趣:

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

注意,更好的解决方案是更改foo以使用对象而不是单独的参数。