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

如何使用泛型类型访问对象并解决类型检查报错

问题解决方法

错误根源在于TypeScript无法推断this.locators(即ObjType[T][F])必然包含input字段——因为form2.item1没有input属性,当用form2和item1实例化类时,this.locators不存在该字段,导致类型检查不通过。

以下是两种无需额外定义interface/type的解决方式,严格遵循从const obj自动推断类型的要求:

方式一:自定义类型守卫明确类型

添加一个类型守卫函数,帮助TypeScript在编译时识别this.locators是否包含input字段:

const obj = {
    form1: {
        item2: {
            checkbox: 'checkbox',
            input: 'input',
        }
    },
    form2: {
        item1: {
            checkbox: 'busin'
        }
    }
};

type ObjType = typeof obj;
type ProgramKeys = keyof ObjType;
type FormKeys<T extends ProgramKeys> = keyof ObjType[T];

// 自定义类型守卫,判断对象是否包含合法的input字段
function hasInput<T>(obj: T): obj is T & { input: string } {
    return 'input' in obj && typeof obj.input === 'string';
}

class CheckboxFormOne<T extends ProgramKeys, F extends FormKeys<T>> {
    locators: ObjType[T][F];

    constructor(public program: T, public form: F) {
        this.locators = obj[program][form];
    }

    fillInput(input: keyof ObjType[T][F]) {  
        if (hasInput(this.locators) && input === 'input') {
            // 此处TypeScript能正确识别this.locators包含input属性
            console.log(this.locators.input);
        }
    }
}

new CheckboxFormOne('form1', 'item2').fillInput('input');
// 若尝试调用 new CheckboxFormOne('form2', 'item1').fillInput('input'),TypeScript会直接报错

方式二:给方法添加泛型约束,限制仅合法场景可调用

通过泛型约束,让fillInput方法仅在ObjType[T][F]包含input字段时才能被调用,从根源避免非法调用:

const obj = {
    form1: {
        item2: {
            checkbox: 'checkbox',
            input: 'input',
        }
    },
    form2: {
        item1: {
            checkbox: 'busin'
        }
    }
};

type ObjType = typeof obj;
type ProgramKeys = keyof ObjType;
type FormKeys<T extends ProgramKeys> = keyof ObjType[T];

class CheckboxFormOne<T extends ProgramKeys, F extends FormKeys<T>> {
    locators: ObjType[T][F];

    constructor(public program: T, public form: F) {
        this.locators = obj[program][form];
    }

    // 泛型约束:仅当input是'input'且属于当前locators的key时,允许调用方法
    fillInput<InputKey extends keyof ObjType[T][F]>(
        input: InputKey extends 'input' ? 'input' : never
    ) {  
        // 此处TypeScript已能推断this.locators必然包含input属性
        console.log(this.locators.input);
    }
}

new CheckboxFormOne('form1', 'item2').fillInput('input');
// new CheckboxFormOne('form2', 'item1').fillInput('input') 会直接报错,因为input不是合法参数

核心逻辑说明

  • 方式一通过类型守卫在运行时验证属性存在性,同时为TypeScript提供编译时类型提示;
  • 方式二通过泛型约束缩小方法的适用范围,直接阻止非法场景的调用,更符合类型安全的设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:52:36