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

如何用keyof为React通用表单变更处理器正确添加类型?

如何为通用React表单变更处理器添加正确的TypeScript类型

我有多个React表单,想要实现一个通用的表单变更处理器来更新状态对象的不同字段,需要为该处理器添加合适的类型约束,让错误的字段值调用触发编译错误。现有代码示例如下:

interface Data {
    a: string;
    b: number;
}

let data: Data = {a: "a", b: 1};

function changeHandler<T>(field: keyof Data, value: T) {
    data = {...data, [field]: value}
}

// 应该通过编译
changeHandler("a", "aa");
changeHandler("b", 11);

// 应该触发编译错误
changeHandler("a", 1);
changeHandler("b", "b");

console.log(data);

注:示例已简化,实际应用中使用React.useState替代let变量。


解决方案:通过泛型关联字段名与值类型

原代码中的泛型T是独立的,TypeScript无法建立field和value之间的类型关联,导致错误调用无法被检测。我们需要用泛型参数绑定字段名和对应值类型,实现强类型约束:

正确的类型实现

interface Data {
    a: string;
    b: number;
}

let data: Data = {a: "a", b: 1};

// 泛型K约束为Data的字段名,value类型固定为该字段对应的类型
function changeHandler<K extends keyof Data>(field: K, value: Data[K]) {
    data = {...data, [field]: value};
}

// 正常通过编译
changeHandler("a", "aa");
changeHandler("b", 11);

// 触发编译错误(类型不匹配)
changeHandler("a", 1); // 类型“number”不能赋值给类型“string”
changeHandler("b", "b"); // 类型“string”不能赋值给类型“number”

console.log(data);

原理说明

  • 泛型K被限制为keyof Data,只能传入Data的合法字段名
  • value的类型直接指定为Data[K],即当前字段K在Data中定义的类型
  • 这样TypeScript会在编译时自动校验:传入的value必须和field对应的字段类型完全匹配,错误调用会直接触发编译报错

React项目中的实际应用(结合useState)

在React场景下,结合useState的写法如下:

import { useState } from 'react';

interface Data {
    a: string;
    b: number;
}

function MyForm() {
    const [data, setData] = useState<Data>({a: "a", b: 1});

    const changeHandler = <K extends keyof Data>(field: K, value: Data[K]) => {
        setData(prevState => ({...prevState, [field]: value}));
    };

    return (
        <div>
            <input 
                type="text" 
                value={data.a} 
                onChange={(e) => changeHandler("a", e.target.value)} 
            />
            <input 
                type="number" 
                value={data.b} 
                onChange={(e) => changeHandler("b", Number(e.target.value))} 
            />
        </div>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:03:30