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

如何从泛型对象中通过键获取正确的值类型?

解决TypeScript映射器中“Property 'a' does not exist on type 'TState[Key]'”错误

问题出在你的泛型定义过于宽泛,导致TypeScript无法在判断key === 'obj'时自动推断value的具体类型。原代码中TState可以是IListState的任意子类型,Key是TState的任意键,编译器无法保证当key为obj时,TState[Key]一定包含a属性。

下面是几种可行的修复方案:

方案一:简化泛型,固定关联IListState

直接移除不必要的TState泛型,让映射器明确针对IListState类型,这样当key缩小到obj时,编译器能正确识别value的类型:

interface IListState {
    name: string;
    age: number;
    isValid: boolean;
    obj: {
        a: number;
    }
}

// 泛型仅保留Key,绑定到IListState的键
type TChangeMapper = <Key extends keyof IListState>(
    key: Key,
    value: IListState[Key]
) => unknown;

const mapper: TChangeMapper = (key, value) => {
    if (key === 'obj') {
        return value.a; // 编译器现在能正确识别value是IListState['obj']
    }
};

const result = mapper('obj', { a: 123 });

方案二:使用类型断言快速修复(适合简单场景)

如果需要保留原泛型结构,可以用类型断言直接告知编译器当前value的类型:

interface IListState {
    name: string;
    age: number;
    isValid: boolean;
    obj: {
        a: number;
    }
}

type TChangeMapper = <
    TState extends IListState = IListState,
    Key extends keyof TState = keyof TState,
>(
    key: Key,
    value: TState[Key]
) => unknown;

const mapper: TChangeMapper = (key, value) => {
    if (key === 'obj') {
        // 断言value为IListState['obj']类型
        return (value as IListState['obj']).a;
    }
};

const result = mapper('obj', { a: 123 });

方案三:用类型守卫做安全类型缩小(推荐复杂场景)

定义一个类型守卫函数,让编译器更安全地判断value的类型:

interface IListState {
    name: string;
    age: number;
    isValid: boolean;
    obj: {
        a: number;
    }
}

// 类型守卫:判断value是否为IListState['obj']类型
function isObjValue(value: unknown): value is IListState['obj'] {
    return typeof value === 'object' && value !== null && 'a' in value;
}

type TChangeMapper = <Key extends keyof IListState>(
    key: Key,
    value: IListState[Key]
) => unknown;

const mapper: TChangeMapper = (key, value) => {
    if (key === 'obj' && isObjValue(value)) {
        return value.a; // 编译器能通过类型守卫确定value的类型
    }
};

const result = mapper('obj', { a: 123 });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:16:15