【问题标题】:unwrapping object for passing as function arguments展开对象以作为函数参数传递
【发布时间】:2019-05-21 15:37:05
【问题描述】:

如果我们有这样的函数:

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

还有一个像这样的对象:

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

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

foo(...obj)

【问题讨论】:

  • 你可以这样试试 foo(...obj: any)

标签: function typescript types parameter-passing


【解决方案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 以接收对象而不是单独的参数。

【讨论】:

    【解决方案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);
    

    【讨论】:

    • 是的,如果 foo 可以更改,那绝对是可行的方法。
    猜你喜欢
    • 2018-02-23
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 2018-07-06
    相关资源
    最近更新 更多