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

能否使用keyof typeof操作符结合数字枚举动态调用TypeScript类静态函数?

如何通过keyof typeof实现类静态函数的动态调用?

场景与问题描述

我想通过索引器动态调用类的静态函数,现有代码如下:

定义静态函数的类(Comparer.ts)

class Comparer {
    static strings(a: string, b: string) {
        return a.localeCompare(b);
    }

    static numbers(a: number, b: number) {
        return a > b ? 1 : a < b ? -1 : 0;
    }
}

对应函数的数字枚举(Comparers.ts)

enum Comparers {
    strings,
    numbers,
}

尝试的调用代码(index.ts)

type ComparerKey = keyof typeof Comparer;

const result = Comparer[Comparers.strings as ComparerKey]("a", "b");
console.log(result);

出现的错误

This expression is not callable.
Not all constituents of type 'Comparer | ((a: string, b: string) => number) | ((a: number, b: number) => 1 | -1 | 0)' are callable.
Type 'Comparer' has no call signatures.ts(2349)

Conversion of type 'Comparers' to type '"prototype" | "strings" | "numbers"' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.ts(2352)

我理解问题出在:keyof typeof会包含不可调用的prototype成员,同时数字枚举值无法直接转换为类的静态成员键类型。

我已知一种无需keyof typeof的方案——使用字符串枚举:

enum Comparers {
     strings = "strings",
     numbers = "numbers",
}
const result = Comparer[Comparers.strings]("a", "b"); // 无报错
console.log(result);

问题:在该场景下,是否可以使用keyof typeof操作符实现静态函数的调用?


解决方案

可以实现,核心是缩小类型范围并正确处理枚举到键的类型转换:

1. 定义仅包含可调用静态方法的键类型

使用Exclude工具类型排除keyof typeof Comparer中的非函数成员(比如prototype):

type CallableComparerKey = Exclude<keyof typeof Comparer, "prototype">;

2. 处理数字枚举到键类型的转换

数字枚举的枚举值是数字类型,直接转换为字符串键类型会触发类型检查错误,需要先转成unknown再转目标类型:

const result = Comparer[Comparers.strings as unknown as CallableComparerKey]("a", "b");

3. 完整可运行示例

class Comparer {
    static strings(a: string, b: string) {
        return a.localeCompare(b);
    }

    static numbers(a: number, b: number) {
        return a > b ? 1 : a < b ? -1 : 0;
    }
}

enum Comparers {
    strings,
    numbers,
}

// 仅保留可调用的静态方法键
type CallableComparerKey = Exclude<keyof typeof Comparer, "prototype">;

// 动态调用示例
const stringCompareResult = Comparer[Comparers.strings as unknown as CallableComparerKey]("a", "b");
console.log(stringCompareResult); // 输出 1

const numberCompareResult = Comparer[Comparers.numbers as unknown as CallableComparerKey](3, 2);
console.log(numberCompareResult); // 输出 1

可选:添加枚举类型验证

如果需要确保枚举的键和类的静态方法名完全匹配,可以添加类型验证:

// 验证枚举的每个键是否都对应可调用的静态方法
type VerifyComparerEnum = {
    [K in keyof typeof Comparers]: K extends CallableComparerKey ? true : never;
};
// 若枚举中添加了不在CallableComparerKey中的键,此处会触发类型错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:28:08