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

TypeScript如何定义适配任意Record的泛型函数校验值与对应key类型匹配

实现方案

方案1:柯里化封装(贴合你给出的调用习惯)

由于目前 TypeScript 不支持在单次泛型调用中混合手动指定参数和自动推断参数,因此可以通过柯里化拆分泛型层级,第一层手动指定目标Record类型,第二层自动推断key和对应value的类型:

// attribute_helper.ts
export function setAttribute<T>() {
  return function <K extends keyof T>(key: K, value: T[K]): void {
    // 此处写你的业务逻辑
  }
}

调用示例:

import { setAttribute } from './attribute_helper'

type Human = {
  name: (name: string) => void
  age: (age: number) => void
}

function setName(name: string): void {
  // ...
}
function setAge(age: number): void {
  // ...
}

// 合法调用
setAttribute<Human>()('name', setName)
setAttribute<Human>()('age', setAge)

// 非法调用,TS会直接抛出类型错误
setAttribute<Human>()('age', setName)

你提到的适配其他Record类型的需求也可以直接满足:

type Cat = {
  food: (food: string) => void
}
function giveFood(food: string): void {}

setAttribute<Cat>()('food', giveFood) // 合法

注:调用时多出来的一对空括号是柯里化的必要写法,如果你完全不想加这层括号,目前TypeScript类型系统暂不支持对应的语法,这是当前版本下最贴合你需求的实现方式。

方案2:传入目标实例(无需手动指定泛型)

如果你的业务场景中存在对应Record类型的实例,可以直接把实例作为第一个参数,TypeScript会自动推断出泛型类型,不需要手动指定:

// attribute_helper.ts
export function setAttribute<T, K extends keyof T>(target: T, key: K, value: T[K]): void {
  target[key] = value
  // 其他业务逻辑
}

调用示例:

const human: Human = {} as Human
setAttribute(human, 'name', setName) // 自动推断类型,调用更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:36:03