在TypeScript中使用解构和休息输入类型化的函数参数 [英] Typed function parameters using destructuring and rest in TypeScript

查看:53
本文介绍了在TypeScript中使用解构和休息输入类型化的函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个功能:

export default ({
  input: { name, onChange, value, ...restInput },
  meta,
  ...rest
}) => (
  ...
);

鉴于名称"是一个字符串,"onChange"是一个函数,值"是一个字符串,元"是一个对象,如何为这些参数添加类型?我最好的猜测是这样的:

Given that 'name' is a string, 'onChange' is a function, 'value' is a string, 'meta' is an object, how can I add types to those parameters? My best guess would be like so:

export default ({
  input: { (name: String), (onChange: function), (value: String), ...restInput },
  (meta: Object),
  ...rest
}) => (
  ...
);

但是它似乎有语法错误.而且我什至不知道如何在休息参数中添加类型.

But it seems to have syntax errors. And even more I have no idea how to add types to rest parameters.

推荐答案

要将类型声明添加到已分解的参数中,您需要声明包含 object 的类型.

To add type declarations to destructured parameters you need to declare the type of the containing object.

来自打字稿文档:

...令人困惑的是,此处的冒号没有指出类型.如果指定了类型,则在整个解构之后仍需要编写类型.

... Confusingly, the colon here does not indicate the type. The type, if you specify it, still needs to be written after the entire destructuring...

let { a, b }: { a: string, b: number } = o;

关于深度嵌套的结构破坏的PSA :

谨慎使用破坏力.如前面的示例所示,除最简单的解构表达式之外的任何事情都令人困惑.对于深度嵌套的解构尤其如此,即使不堆积重命名,默认值和类型注释,也很难理解.尝试使解构表达式小而简单.您总是可以编写解构会产生自己的赋值.

Use destructuring with care. As the previous example demonstrates, anything but the simplest destructuring expression is confusing. This is especially true with deeply nested destructuring, which gets really hard to understand even without piling on renaming, default values, and type annotations. Try to keep destructuring expressions small and simple. You can always write the assignments that destructuring would generate yourself.

解构函数参数

在函数中,这是您声明结构化参数的类型的方式:

Destructuring function parameters

In a function, this is how you would declare types for destructured parameters:

export default ({ a, b }: {a: string, b: number}) => (
  ...
);

在更长的示例中,这看起来很糟糕:

This looks pretty bad on a longer example though:

export default ({
  input: { name, onChange, value, ...restInput },
  meta,
  ...rest
}: {
  input: { 
    name: string, onChange: ()=>void, value:string, ...restInput 
  }, meta: object
}) => (
  ...
);

看起来很糟糕,因此您可以在这里做的最好的事情是为您的参数声明一个接口,并使用该接口代替内联类型:

Looks pretty bad, so the best you can do here is to declare an interface for your parameters and use that instead of inline types:

interface Params {
  input: { 
    name: string;
    onChange: ()=>void;
    value: string;
  }; 
  meta: object;
}

export default ({
  input: { name, onChange, value, ...restInput },
  meta,
  ...rest
}: Params) => {};

包含更多内容的文章

对于其余参数,取决于您期望这些类型是什么,可以使用索引签名:

For the rest parameters, depending on what you expect these types to be, you can use a index signature:

interface Params {
  // This needs to match the other declared keys and values
  [key: string]: object;
  input: { 
    [key: string]: string | (() => void);
    name: string;
    onChange: ()=>void;
    value: string;
  }; 
  meta: object;

}

export default ({
    input: { name, onChange, value, ...restInput },
    meta,
    ...rest
}: Params) => { };

例如,这将为 ... rest 提供一种 {[key:string]:object} 类型.

This will give ...rest a type of {[key: string]: object} for example.

查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆