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

使用if语句作为类型守卫,TypeScript未识别类型收窄

TypeScript无法识别in操作符的类型收窄问题

用户定义的对象与函数代码:

const datas = {
    a: {
        "0": 0,
        "1": 1
    },
    b: {
        "0": 0
    }
}

function index (data: keyof typeof datas, prop: "0"|"1") {
    if(prop in datas[data]) {
        return datas[data][prop] // <- 此处报错
    }
}

TypeScript抛出的错误:

Element implicitly has an 'any' type because expression of type "0" | "1" can't be used to index type '{ "0": number; "1": number; } | { "0": number; }'.
  Property '1' does not exist on type '{ "0": number; "1": number; } | { "0": number; }'.ts(7053)

尽管通过if(prop in datas[data])做了属性存在性检查,但TypeScript无法自动对联合类型进行收窄,导致报错。


解决方法

方案1:使用类型断言直接指定类型

既然已经通过in确认属性存在,可通过类型断言明确告诉TypeScript访问是安全的:

function index (data: keyof typeof datas, prop: "0"|"1") {
    if(prop in datas[data]) {
        return (datas[data] as Record<typeof prop, number>)[prop]
    }
}

方案2:自定义类型守卫函数

编写专门的类型守卫,帮助TypeScript正确识别类型收窄逻辑:

type DataValue = typeof datas[keyof typeof datas];

function hasProp<T extends DataValue, K extends "0" | "1">(obj: T, prop: K): obj is T & Record<K, number> {
    return prop in obj;
}

function index (data: keyof typeof datas, prop: "0"|"1") {
    const target = datas[data];
    if(hasProp(target, prop)) {
        return target[prop];
    }
}

方案3:重构数据类型定义

提前为datas定义更精确的类型,让TypeScript能更准确地推断参数与返回值类型:

type DataMap = {
    a: { "0": number; "1": number },
    b: { "0": number }
}

const datas: DataMap = {
    a: {
        "0": 0,
        "1": 1
    },
    b: {
        "0": 0
    }
}

function index<K extends keyof DataMap, P extends keyof DataMap[K]>(data: K, prop: P) {
    return datas[data][prop];
}

该方案还能限制函数参数的合法性,避免传入不存在的prop值。


内容的提问来源于stack exchange,提问作者Onii-Chan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:05:26