typescript 解构函数参数对象并...rest

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50288205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:24:08  来源:igfitidea点击:

Destructuring a function parameter object and ...rest

typescript

提问by marko

I'd like to write a function that takes an object parameter and captures all the remaining parameters in a variable. The goal is to allow the function to receive named parameters (as opposed to positional parameters), some of them optional, and set default values in the function. So, in pseudo code something like this:

我想编写一个函数,它接受一个对象参数并捕获一个变量中的所有剩余参数。目标是允许函数接收命名参数(与位置参数相反),其中一些是可选的,并在函数中设置默认值。所以,在伪代码中是这样的:

interface IMyProps {
  a: string
  b?: number
}

const myfun1 = (p: {a: string, b?:number, ...rest}) => {
  const {a, b = 'hello'} = p;
}

What would be the best way to achieve this in Typescript 2.0?

在 Typescript 2.0 中实现这一目标的最佳方法是什么?

采纳答案by jcalz

I think object destructing with the rest operatorin TypeScript corresponds to the index signatureon the type of the destructured object if you have pulled off all the explicitly named properties already. That means you would have the same restriction where the types of the rest properties would have to be at least as wide as the union of all the explicitly labeled properties. In your case, you could extend IMyPropswith an index signature like this:

如果您已经取消了所有显式命名的属性,我认为在 TypeScript 中使用 rest 运算符进行的对象解构对应于解构对象类型的索引签名。这意味着您将具有相同的限制,其中其余属性的类型必须至少与所有显式标记属性的并集一样宽。在您的情况下,您可以IMyProps使用这样的索引签名进行扩展:

interface IMyPropsWithIndex {
  a: string
  b?: number
  [k: string]: string | number | undefined
}

since the type of ais stringand the type of bis number | undefined. You could add more stuff to the union but you couldn't make it something narrower like string. If that's okay with you, then the way to do destructuring would be something like this:

因为aisstring的类型和bis的类型number | undefined。你可以向联合添加更多的东西,但你不能让它更窄,比如string. 如果这对您没问题,那么进行解构的方法将是这样的:

const myfun1 = (p: IMyPropsWithIndex) => {
  const { a, b = 'hello' , ...rest } = p;
  a; // string
  b; // number | 'hello'
  rest; // {[k: string]: string | number | undefined}
}

If you inspect the types of the variables, you get something like the above.

如果你检查变量的类型,你会得到类似上面的内容。

That's probably the best you can do with typing the rest properties. Ideally you could use generics, but you can't use the rest/spread operator with generics as of now, and there is an open issue in GitHubtracking this.

这可能是您输入其余属性所能做的最好的事情。理想情况下,您可以使用泛型,但截至目前,您不能将 rest/spread 运算符与泛型一起使用,并且GitHub 中有一个未解决的问题正在跟踪此问题。

Hope that helps. Good luck.

希望有帮助。祝你好运。

回答by klugjo

You can use destructuring assignment directly in the function arguments:

您可以直接在函数参数中使用解构赋值:

interface IMyType { 
    a: number;
    b: number;
    c: number;
    d: number;
    [k: string]: number; // use this if you don't know the name of the properties in 'rest'
}

const obj: IMyType = { a: 1, b: 2, c: 3, d: 4 }

// Normal destructuring
const { a, b, ...rest } = obj;
console.log(rest); // {c: 3, d: 4}

// Directly in function arguments
const fn = ({ a, b, ...rest }: IMyType) => { console.log(rest); }

console.log(fn(obj)); // {c: 3, d: 4}