You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:25:05