为什么TypeScript无法推断该场景下的关联类型?
问题背景
const foo = (flag: boolean) => { if (flag) { return { success: true, data: { name: "John", age: 40 } } } return { success: false, data: null } } const result = foo(true); if (result.success) { console.log(result.data.name); // TS error: 'result.data' is possibly 'null' }
问题:当调用foo(true)并判断result.success为true时,TypeScript为何无法推断data一定存在?我知道可以通过定义函数返回类型解决该问题,但希望TypeScript能自动完成推断。
原因解析
TypeScript对函数返回值的自动类型推断逻辑是合并所有返回分支的类型,但默认不会保留分支间的关联关系:
- 函数
foo的两个返回分支,TypeScript会将它们合并为一个单一的对象类型:{ success: boolean; data: { name: string; age: number } | null; } - 它无法识别“
success为true时data非空,success为false时data为null”这种依赖关系,自然也就无法通过result.success的判断来缩小data的类型。 - 另外,即使你传入的是字面量
true,函数的返回值类型在定义阶段就已经被推断完成,不会根据调用时的入参动态细化类型。
无需显式定义返回类型的解决办法
如果不想手动定义函数返回类型,可以给每个返回分支的success字段加上as const,强制TypeScript推断出字面量类型而非宽泛的boolean:
const foo = (flag: boolean) => { if (flag) { return { success: true as const, data: { name: "John", age: 40 } } } return { success: false as const, data: null } }
此时TypeScript会自动将foo的返回类型推断为带鉴别符的联合类型:
{ success: true; data: { name: string; age: number; }; } | { success: false; data: null; }
后续判断result.success为true时,TypeScript就能正确识别data一定存在,不会再抛出错误。
内容的提问来源于stack exchange,提问作者Raul
相关产品推荐
相关产品推荐

