打字稿中默认值的参数类型

时间:2019-08-09 17:52:12

标签: typescript typescript-typings

我用一个参数(用于解构)和一个添加处理程序的函数声明了一个“处理程序函数”类型

type HandlerArg = any;
type MyHandler = (event?: HandlerArg) => any;

function AddHandler(handler: MyHandler) {}

但是当我使用默认值声明参数时,类型会推断为any

AddHandler(({
  id = 1, // the type is "any"
}) => {
  console.log(id)
});

AddHandler(({
  children = [], // the type is "any"
}) => {
  console.log(children.length)
});

如何设置类型而不用编写下一个代码?

AddHandler(({
  id = 0,
  name = '',
}: { // this is very ugly
  id: number,
  name: string,
}) => {
  console.log(id);
  console.log(name);
});

1 个答案:

答案 0 :(得分:0)

设计类型任何,因为这是您声明MyHandlerHandlerArg类型的方式-该函数需要一个类型为实参的函数任何。

仅因为您将特定处理程序实例的默认值设置为数字或数组,就不会更改处理程序函数期望的类型。

您可以创建期望某些类型的特定处理程序,并使用addHandler添加它们(顺便说一下,JavaScript中函数名称的约定为camelCased),例如:

const handlerWithNumber = (id: number = 1) => {
    console.log(id); // id is a number in Typescript
}

addHandler(handlerWithNumber);

因此,尝试用数字以外的任何字符调用handlerWithNumber会导致打字稿出现编译错误。

handlerWithNumber(2); // Works.
handlerWithNumber("2"); // Error, Typescript won't compile this.

从您的问题出发,不清楚您打算如何使用这些处理程序,以及为什么/如何处理这些处理程序参数的类型信息很重要。但是您需要了解Typescript类型仅在设计时在Typescript中具有含义。

Typescript将您的代码编译为纯Javascript,因此所有类型信息在运行时都会丢失,您将只能使用纯Javascript类型。如果需要在运行时对参数的类型进行断言,则需要使用Javascript类型检查技术(typeofinstanceof,类名,检查null / undefined等)。

这也意味着,如果您的代码是使用纯Javascript编写的,那么不管您打算使用哪种Typescript类型,都可以使用任何参数调用此处理程序,因此请停止编写代码。

更新(回复评论)

您还可以使用泛型来声明您的处理程序,添加处理程序时将推断类型,并且可以传递给该处理程序的对象类型将被固化,如下所示:

type MyHandler<T> = (event?: T) => any;
function addHandler<T>(handler: MyHandler<T>) {
    //...
}

// This handler is a function that expects an object with single property
// id of type number (defaults to 1)
const handler = ({ id = 1}) => {
    console.log(id);
}

addHandler(handler);

handler({}); // id = 1
handler({id: 2}); // id = 2
handler({name: ""}); // Error

您可以使用打字稿generic constraints进一步限制所传递对象的接口。