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

TypeScript中表单formData动态属性[name]:value的类型定义方法

React表单动态属性赋值的TypeScript正确写法

你原有JS代码里有个笔误:状态更新方法写的是setForm,和useState定义的setFormData不匹配,需要先修正这个问题。
核心要解决的类型问题是:TS默认将event.target.name推断为通用string类型,无法匹配formData对象的固定键集合,会报隐式any的类型错误。

完整可运行的TS实现代码如下:

import { useState, ChangeEvent } from 'react';

// 表单字段类型定义,字段增减直接修改这里即可
type FormFields = {
  firstName: string;
  lastName: string;
}

function MyForm() {
  // 给useState传入泛型参数,明确状态结构
  const [formData, setFormData] = useState<FormFields>({
    firstName: "",
    lastName: "",  
  });

  // 标注事件为input元素的变更事件类型
  const handleFormChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target;
    setFormData(prev => ({
      ...prev,
      // 核心:断言name为表单的合法键名,解决动态属性赋值的类型校验问题
      [name as keyof FormFields]: value
    }));
  };

  return (
    <div>
      <input name="firstName" value={formData.firstName} onChange={handleFormChange} />
      <input name="lastName" value={formData.lastName} onChange={handleFormChange} />
    </div>
  )
}

关键逻辑说明

  • 如果你不想单独写FormFields类型,也可以直接用TS的类型推导能力,动态属性处写[name as keyof typeof formData]即可,效果完全一致,适合字段多、不想重复写类型定义的场景。
  • keyof FormFields得到的类型是'firstName' | 'lastName'的联合类型,相当于告诉TS:当前拿到的name值一定是表单里已经定义的合法字段,不会出现未知键。
  • 如果你的表单里有select、textarea元素,只需要把事件泛型里的HTMLInputElement替换成对应的HTMLSelectElement/HTMLTextAreaElement就行。

注意:TS只能做编译期校验,你需要保证所有表单项的name属性值和类型里定义的字段名完全一致,否则运行时会写入错误的字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:24:18