在TypeScript中使用解构和休息输入类型化的函数参数

时间:2018-11-16 00:06:21

标签: javascript typescript types destructuring

我有一个功能:

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

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

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

但是它似乎有语法错误。甚至我都不知道如何将类型添加到剩余参数。

1 个答案:

答案 0 :(得分:9)

要将类型声明添加到结构化参数中,您需要声明包含的 object 的类型。

来自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