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

TypeScript条件判断后无法收窄类型,报ip属性不存在错误

TypeScript类型收窄失效:Property 'ip' does not exist on type 'IpDetails | Error'

遇到如下TypeScript错误:

Property 'ip' does not exist on type 'IpDetails | Error'.
  Property 'ip' does not exist on type 'Error'.ts(2339)

即便使用"message" in res检查或isError类型守卫收窄类型,错误依然存在。

问题原因

你自定义的Error接口和JavaScript全局内置的Error类重名了,TypeScript会优先绑定全局的Error类型(对应原生错误对象,自带message、name等属性,但没有你定义的error属性),导致你的类型守卫无法正确识别自定义的错误结构,自然无法完成类型收窄。

解决方案

重命名自定义的错误接口,避免和全局类型冲突,同步调整相关代码即可解决:

  1. 重命名自定义错误接口,比如改为ApiError
  2. 更新类型守卫函数的参数与返回类型
  3. 修改getIpData的返回Promise类型

修正后的完整代码:

interface IpDetails {
    ip : string,
}

// 重命名接口,避免和全局Error冲突
interface ApiError {
    error: {
        code : number,
        message: string,
    },
}

let collection: IpDetails[] = [];

// 调整类型守卫的参数和返回类型
function isApiError(res: IpDetails | ApiError): res is ApiError {
    return (res as ApiError).error !== undefined;
}

const getIpData = async (ipAddress: string, config: any = {}): Promise<IpDetails|ApiError> => {
  return new Promise((resolve, reject) => {
     resolve({ip : '1.1.1.1'});
  });
}

(async () => {
    let res = await getIpData('1.1.1.1');

    if (!isApiError(res)) {
        let duplicate = collection.find(entry => entry.ip === res.ip); // 错误消失
    }
})();

如果想用in操作符做类型收窄,同样要使用重命名后的接口:

if (!('error' in res)) {
    let duplicate = collection.find(entry => entry.ip === res.ip);
}

补充说明

全局Error是TypeScript内置的原生类型,和你自定义的结构完全不同。永远不要用内置全局类型的名称来定义自己的接口/类型,避免这类命名冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:52:14