【问题标题】:Typed function parameters using destructuring and rest in TypeScript在 TypeScript 中使用解构和休息的类型化函数参数
【发布时间】:2019-04-19 03:42:07
【问题描述】:

我有一个函数:

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

鉴于 'name' 是一个字符串,'onChange' 是一个函数,'value' 是一个字符串,'meta' 是一个对象,我如何为这些参数添加类型? 我最好的猜测是这样的:

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

但它似乎有语法错误。更我不知道如何将类型添加到其余参数。

【问题讨论】:

    标签: javascript typescript types destructuring rest-parameters


    【解决方案1】:

    要向解构参数添加类型声明,您需要声明包含对象的类型。

    来自typescript documentation

    ... 令人困惑的是,这里的冒号并不表示类型。类型,如果指定的话,还是需要在整个解构之后写...

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

    关于深度嵌套解构的 PSA

    谨慎使用解构。正如前面的示例所展示的,除了最简单的解构表达式之外的任何东西都令人困惑。对于深度嵌套的解构尤其如此,即使没有重命名、默认值和类型注释,也很难理解。 尽量保持解构表达式的小而简单。您始终可以编写解构将自己生成的赋值。

    解构函数参数

    在函数中,您可以这样声明解构参数的类型:

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

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

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

    看起来很糟糕,所以在这里你能做的最好的事情就是为你的参数声明一个接口并使用它而不是内联类型:

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

    Playground

    Article with much more

    休息参数

    对于其余参数,根据您对这些类型的期望,您可以使用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} 例如。

    Rest parameter playground

    【讨论】:

    • 是的,我认为界面是这里的最佳选择。但是我们通常不输入'...rest'吗?
    • 这取决于您对对象的期望。我添加了一个使用索引签名的选项
    • 如何在 TypeScript 中为解构参数添加默认值?在普通的 ES2015 中,这很简单,function foo({ param1, param2, optionalParam = 0 })
    猜你喜欢
    • 2021-07-24
    • 2019-01-29
    • 1970-01-01
    • 2019-06-28
    • 2019-03-07
    • 2023-03-23
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多