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

TypeScript如何通过构造函数推导类型,避免重复指定键名?

TypeScript 简化FilterEqual类的泛型参数写法

现有如下代码:

class User {
    public name: string
    public age: number
}

class FilterEqual<T, K extends keyof T> {
    constructor(field: K, public value: T[K]) {}
}

new FilterEqual<User, 'name'>('name', '')

这段代码能实现严格的类型校验:field必须是User的键之一,value的类型必须和所选键的类型匹配,错误用法会直接报错:

new FilterEqual<User, 'invent'>('invent', '') // 字段不存在,报错
new FilterEqual<User, 'name'>('name', 1) // 类型不匹配,报错

但这种写法需要重复指定键名(既要在泛型参数里写'name',又要在构造函数参数里传'name'),能不能简化成只传入User泛型的写法?比如:

new FilterEqual<User>('name', '')

我尝试过把类的泛型简化成只保留T,但这样会失去类型校验的严格性,允许错误的实例创建:

class FilterEqual<T> {
    constructor(field: keyof T, public value: T[keyof T]) {}
}

// 这种写法不会报错,但明显不符合预期
new FilterEqual<User>('name', 1)

解决方案

将泛型K从类的泛型参数移到构造函数的泛型参数中,让TypeScript自动推导K的类型:

class User {
    public name: string
    public age: number
}

class FilterEqual<T> {
    constructor<K extends keyof T>(field: K, public value: T[K]) {}
}

// 正确用法,无需重复指定键名
new FilterEqual<User>('name', '')
new FilterEqual<User>('age', 25)

// 错误用法依旧会触发类型报错
new FilterEqual<User>('invent', '') // 字段不存在,报错
new FilterEqual<User>('name', 1) // 类型不匹配,报错

原理说明

把K作为构造函数的泛型参数后,TypeScript会根据你传入的field参数自动推导出K的具体值,同时约束value的类型必须严格匹配T[K],既保留了原始代码的类型校验能力,又省去了重复指定键名的冗余操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:55:37