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
相关产品推荐
相关产品推荐

