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

如何在TypeScript中根据值类型提取键并约束函数入参?

问题场景

我们先定义如下的Test接口及对应实例:

interface Test {
    hello: () => 'Hello World!'
    test: 1
}

const test: Test = {
    hello () {
        return 'Hello World!'
    },
    test: 1
}

我们可以实现一个根据键获取对象值的通用函数:

function getTestValue<Key extends keyof Test> (key: Key): Test[Key] {
    return test[key]
}

现在需要实现一个仅能获取值为函数类型的键的函数。如果用运行时判断非函数值就抛错的方式,属于临时方案:

function getTestMethod<Key extends keyof Test> (key: Key): Test[Key] {
    const method = test[key]

    if (typeof method !== 'function') throw new Error('Method is not a function')

    return method
}

这种写法的问题是,IntelliSense会提示Test的所有键(包括非函数类型的test),很容易引发bug,这正是我们想用TypeScript类型系统提前规避的问题。

那怎么通过TypeScript类型系统实现仅允许传入值为函数的键?

解决方案

可以通过条件类型筛选出Test中值为函数类型的键,具体实现如下:

1. 定义工具类型提取函数键

先写一个通用工具类型,用来提取任意对象类型中值为函数的键:

type FunctionKeys<T> = {
    [K in keyof T]: T[K] extends Function ? K : never
}[keyof T]

这个类型的逻辑是:遍历对象T的所有键K,判断T[K]是否为函数类型;如果是,就保留键名K,否则返回never;最后通过[keyof T]取出所有有效键的联合类型。

2. 用工具类型约束函数参数

将上述工具类型应用到目标函数的泛型约束中:

function getTestMethod<Key extends FunctionKeys<Test>>(key: Key): Test[Key] {
    return test[key]
}

效果验证

现在使用getTestMethod时,IntelliSense只会提示符合要求的键(比如这里的hello);如果传入非函数类型的键(比如test),TypeScript会直接在编译阶段报错:

getTestMethod('hello') // 正常,返回类型为 () => 'Hello World!'
getTestMethod('test') // 编译报错:类型'"test"'的参数不能赋给类型'"hello"'的参数

这种方式完全通过类型系统实现了需求,不需要依赖运行时判断,从根源上避免了误传键名的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:37:32