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

TypeScript如何让函数识别参数为两个接口类型之一?

解决TypeScript联合类型参数的类型识别问题

我有个函数,参数是两种不同的payload联合类型,代码如下:

interface payload1 {
    userId: string;
    partnerId: string;
} 

interface payload2 {
    userToken: string;
    partnerKey: string;
}

function loadData(input: payload1 | payload2){
    if(input.userId){
        // 通过userId加载数据
    }
}

但TypeScript报错:Property 'userId' does not exist on type 'payload1 | payload2'. Property 'userId' does not exist on type 'payload2'.

下面是几种让TypeScript正确识别参数类型的方法:

方法一:用in操作符做类型守卫

直接检查属性是否存在,TypeScript会自动窄化类型:

function loadData(input: payload1 | payload2){
    if('userId' in input){
        // 这里input会被识别为payload1类型
        console.log(input.userId, input.partnerId);
    } else {
        // 这里自动识别为payload2类型
        console.log(input.userToken, input.partnerKey);
    }
}

方法二:自定义类型守卫函数

如果需要更复杂的判断逻辑,可以写专门的类型守卫函数:

function isPayload1(input: payload1 | payload2): input is payload1 {
    return (input as payload1).userId !== undefined;
}

function loadData(input: payload1 | payload2){
    if(isPayload1(input)){
        console.log(input.userId);
    } else {
        console.log(input.userToken);
    }
}

方法三:给接口添加区分字段(推荐)

如果能修改接口定义,添加一个唯一的区分字段是最清晰的方案,属于TypeScript的可辨识联合类型:

interface payload1 {
    type: 'user-id'; // 唯一标识字段
    userId: string;
    partnerId: string;
} 

interface payload2 {
    type: 'user-token'; // 唯一标识字段
    userToken: string;
    partnerKey: string;
}

function loadData(input: payload1 | payload2){
    if(input.type === 'user-id'){
        console.log(input.userId);
    } else {
        console.log(input.userToken);
    }
}

原因说明

TypeScript处理联合类型时,只有当判断条件能明确区分出具体类型时,才会自动进行类型窄化。直接访问input.userId会报错,因为payload2没有这个属性,TS无法确定当前参数的具体类型。上面几种方法都能让TS明确当前分支的类型,从而正确识别属性。

内容的提问来源于stack exchange,提问作者mdunisch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:15:34