问题描述
我正在阅读《 编程打字稿》 。以下示例说明了优化,我对此感到困惑:
type UserTextEvent = { value: string; target: HTMLInputElement };
type UserMouseEvent = { value: [number,number]; target: HTMLElement };
type UserEvent = UserTextEvent | UserMouseEvent;
function handle(event: UserEvent) {
if (typeof event.value === "string") {
event.value; // string
event.target; // HTMLInputElement | HTMLElement (1)
// ...
return;
}
event.value; // [number,number]
event.target; // HTMLInputElement | HTMLElement (2)
}
我认为(1)和(2)中event.target的类型分别为 HTMLInputElement 和 HTMLElement 。我的理解是,如果event.value的类型是确定的,则event.target的类型是确定的。但这是 HTMLInputElement | HTMLElement 。有人能比这本书更清楚地解释它吗?谢谢。
解决方法
不幸的是,您只是在检查属性的类型,因此,打字稿将不会采用类类型。为此,您必须使用一种推断类型的方法来检查自己。
type UserTextEvent = { value: string; target: HTMLInputElement };
type UserMouseEvent = { value: [number,number]; target: HTMLElement };
type UserEvent = UserTextEvent | UserMouseEvent;
function isUserTextEvent(event: UserEvent): event is UserTextEvent {
return typeof event.value === "string";
}
function handle(event: UserEvent) {
if (isUserTextEvent(event)) {
event.value; // string
event.target; // HTMLInputElement (1)
// ...
return;
}
event.value; // [number,number]
event.target; // HTMLElement (2)
}
您可以在playground
上查看验证时
typeof event.value === "string"
Typescript只能推断该值实际上是一个字符串,而在其他情况下只能是[number,number]
但是它不能推断value
是HTMLInputElement
或HTMLElement
,因此仍然考虑HTMLInputElement | HTMLElement
。您需要使用一种方法来说实际上事件是UserTextEvent