hli*_*liu 6 type-inference discriminated-union narrowing typescript union-types
如果联合类型的成员共享一个属性,并且该属性的类型可用于区分这些成员,那么我应该能够使用作为条件来缩小if子句中的类型范围typeof。但这不起作用。
例如,在if下面的子句中, 的类型event应推断为UserTextEvent, 的类型event.target应推断为HTMLInputElement:
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, as expected
event.target // should be narrowed to HTMLInputElement, but
// is still HTMLInputElement | HTMLElement. Why?
}
}
Run Code Online (Sandbox Code Playgroud)
以下是在 Typescript 2.0 中添加判别联合支持时支持的判别属性类型:
\n\n\n\n\n
x.p == v判别式属性类型保护是、x.p === v、x.p != v或形式的表达式x.p !== v,其中p和v是字符串文字类型或字符串文字类型的联合的属性和表达式。判别属性类型保护将 x 的类型缩小为具有判别属性 p 和 v 的可能值之一的 x 的构成类型。请注意,我们目前仅支持字符串文字类型的判别属性。我们打算稍后添加对布尔和数字文字类型的支持。
\n
\n\n联合的公共属性现在被视为判别式,只要它们包含某种单例类型(例如字符串文字、null 或未定义),并且它们不包含泛型。
\n因此,TypeScript 3.2 将以下示例中的 error 属性视为判别式,而在此之前它不会\xe2\x80\x99t,因为 Error 是\xe2\x80\x99t 单例类型。因此,缩小功能可以在展开函数的主体中正常工作。
\nRun Code Online (Sandbox Code Playgroud)\ntype Result<T> = { error: Error; data: null } | { error: null; data: T };\nfunction unwrap<T>(result: Result<T>) {\n if (result.error) {\n // Here \'error\' is non-null\n throw result.error;\n }\n // Now \'data\' is non-null\n return result.data;\n}\n
Typescript 4.5 添加了对“模板字符串类型作为判别式”的支持。
\n\n\nTypeScript 4.5 现在可以缩小具有模板字符串类型的值的范围,并且还将模板字符串类型识别为判别式。
\n例如,以下内容过去在 TypeScript 4.5 中失败,但现在成功进行了类型检查。
\nRun Code Online (Sandbox Code Playgroud)\nexport interface Success {\n type: `${string}Success`;\n body: string;\n}\n \nexport interface Error {\n type: `${string}Error`;\n message: string\n}\n \nexport function handler(r: Success | Error) {\n if (r.type === "HttpSuccess") {\n const token = r.body;\n \n(parameter) r: Success\n }\n}Try\n
在所有情况下,用于区分的是判别属性的值,而不是其类型。
\n换句话说,从当前版本的 Typescript 4.5 开始,你就不走运了。只是(尚)不支持。以下是相关的未决问题:
\ntypeof x.y作为判别式缩小范围(#32399)以下是Typescript 开发团队负责人 Ryan Cavanaugh 的评论:
\n\n\n从表面上看,不幸的是,这个功能的实现比我们预期的要复杂得多,而且我们认为在这种情况下成本/效益比并不好。尽管我们非常想支持这种模式,但这些变化的影响感觉太深远了(即使它们对于实际支持该场景是必要的)。我们将保留最初的问题,以防稍后出现更简单的方法,但我们现在不愿意在关键代码路径中引入如此复杂的内容。
\n
| 归档时间: |
|
| 查看次数: |
650 次 |
| 最近记录: |