TypeScript间接推断联合类型:调用函数后如何实现编译时类型确认
TypeScript类型窄化问题
示例代码
type TypeX = {t:"a", a1:string} | {t:"b", a2: string}; let t: TypeX | undefined; function setA(){ t = {t:"a", a1:"values"}; } setA(); console.log(t.a1);
报错信息
Property 'a1' does not exist on type 'TypeX'.
Property 'a1' does not exist on type '{ t: "b"; a2: string; }'.(2339)
问题描述
除了将t断言为{t:"a",a1:string}之外,是否有其他方法可以告知TypeScript:调用setA后,t的类型为{t:"a",a1:string}?
希望实现类似“调用setA函数时,t的类型即为{t:"a",a1:string}”的效果。另外,已知可以通过如下运行时检查实现,但更倾向于编译时检查,且不想额外添加if判断:
if(t && t.t === "a"){ console.log(t.a1); }
解决方案
1. 使用断言函数
定义断言函数,让TypeScript在编译时识别变量的具体类型,运行时会验证逻辑(若不满足则抛出错误,适合确定逻辑正确的场景):
type TypeX = {t:"a", a1:string} | {t:"b", a2: string}; let t: TypeX | undefined; function setA(){ t = {t:"a", a1:"values"}; } // 断言函数:明确t的类型为TypeA function assertIsTypeA(obj: TypeX | undefined): asserts obj is {t:"a", a1:string} { if (!obj || obj.t !== "a") { throw new Error("Expected type A"); } } setA(); assertIsTypeA(t); console.log(t.a1); // 编译通过,TypeScript已识别t的类型
2. 用对象包装变量利用控制流分析
将t放入对象中,TypeScript的控制流分析可以追踪对象属性的类型变化:
type TypeX = {t:"a", a1:string} | {t:"b", a2: string}; // 用对象包装t const state = { t: undefined as TypeX | undefined }; function setA(){ state.t = {t:"a", a1:"values"}; } setA(); console.log(state.t.a1); // 编译通过,TypeScript能识别state.t的具体类型
3. 带断言的函数返回类型
直接给setA添加asserts类型注解,明确调用后t的类型:
type TypeX = {t:"a", a1:string} | {t:"b", a2: string}; type TypeA = Extract<TypeX, {t:"a"}>; let t: TypeX | undefined; // 注解函数调用后t的类型为TypeA function setA(): asserts t is TypeA { t = {t:"a", a1:"values"}; } setA(); console.log(t.a1); // 编译通过
内容的提问来源于stack exchange,提问作者mehran
相关产品推荐
相关产品推荐

