我用一个参数(用于解构)和一个添加处理程序的函数声明了一个“处理程序函数”类型
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);
});
答案 0 :(得分:0)
设计类型是任何,因为这是您声明MyHandler
和HandlerArg
类型的方式-该函数需要一个类型为实参的函数任何。
仅因为您将特定处理程序实例的默认值设置为数字或数组,就不会更改处理程序函数期望的类型。
您可以创建期望某些类型的特定处理程序,并使用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类型检查技术(typeof
,instanceof
,类名,检查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进一步限制所传递对象的接口。