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

TypeScript类方法如何接收interface的keyof并校验参数?

TypeScript Check类test方法的类型校验实现方案

定义的类型与对象

interface Types {
    string: (value: string, letterAllowed: string[]) => boolean;
    number: (value: number, maxNumber: number) => boolean;
}

const types: Types = {
    string: (value: string) => typeof value === "string",
    number: (value: number) => typeof value === "number",
};

核心需求

  • 调用test方法时,必须传入Types的keyof类型参数,否则触发类型报错;
  • 传入的后续参数必须严格匹配对应key的函数除第一个参数外的类型,参数缺失或类型不匹配时触发报错。

期望效果示例

// 报错:参数""不属于"string" | "number"类型
new Check("value").test("");
// 报错:缺少"number"类型对应的maxNumber参数
new Check(5).test("number");
// 无报错:参数完全符合要求
new Check(5).test("number", 10);

之前尝试的代码及报错

首次尝试代码

class Typeof {
    value: any;
    constructor(value: any) {
        this.value = value;
    }
    is<T extends keyof Types>(type: T, ...args: OmitFirstArgument<Types[T]>): boolean {
        return types[type](this.value, ...args);
    }
}

报错信息:TS2556: 展开参数必须是元组类型或传递给剩余参数。

修改后尝试代码

class TypeOf<T> {
    value: T;
    constructor(value: T) {
        this.value = value;
    }
    is<A extends (keyof Types | string)>(name: A, ...args: OmitFirstArgument<Types[A]>) {
        return types[name as any].apply(this, [this.value, ...args]);
    }
}

报错信息:TS2536: 类型"A"不能用于索引类型"Types"。

最终解决方案

步骤1:定义OmitFirstArgument类型工具

明确提取函数除第一个参数外的剩余参数类型:

type OmitFirstArgument<T extends (...args: any[]) => any> = 
  T extends (_: any, ...rest: infer R) => any ? R : never;

步骤2:实现符合需求的Check类

class Check<T> {
    private value: T;

    constructor(value: T) {
        this.value = value;
    }

    test<K extends keyof Types>(type: K, ...args: OmitFirstArgument<Types[K]>): boolean {
        // 通过类型断言确保value匹配对应校验函数的第一个参数类型
        return types[type](this.value as Parameters<Types[K]>[0], ...args);
    }
}

报错原因解析

  1. TS2556报错:原代码中TypeScript无法明确args的元组类型与types[type]的剩余参数类型完全匹配,通过OmitFirstArgument明确提取剩余参数为元组类型,再配合类型断言确保value的类型兼容性,即可解决展开参数的类型校验问题。
  2. TS2536报错:原代码将泛型A扩展为keyof Types | string,当A为普通string类型时,无法索引Types接口。直接限制泛型K为keyof Types,既能满足“必须传入合法key”的需求,又避免了非法索引的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:54:21