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

Solid JS中如何为Setter参数使用泛型键适配表单输入?

解决SolidJS表单状态更新的TypeScript类型错误

问题根源

你遇到的类型错误是因为createSignal推断出的form状态类型是固定的{ username: string; password: string },没有允许任意字符串键的索引签名,导致Setter<{...}>无法兼容Setter<any>,且直接用[name]更新状态时TypeScript会判定为不安全操作。

解决方案

1. 定义带索引签名的表单类型

先扩展表单状态的类型,允许任意字符串键(值类型与已有字段保持一致,这里是string):

type FormState = {
  username: string;
  password: string;
  // 允许添加任意字符串键,值为string类型
  [key: string]: string;
};

2. 创建带明确类型的表单信号

用上面定义的FormState约束createSignal的类型,确保setForm的类型支持任意键更新:

const [form, setForm] = createSignal<FormState>({
  username: '',
  password: ''
});

3. 子组件的类型适配

给InputText子组件定义正确的props类型,避免使用any,保证类型安全:

type InputTextProps = {
  name: string;
  value: string;
  setForm: Setter<FormState>;
};

function InputText({ name, value, setForm }: InputTextProps) {
  const handleChange = (e: Event) => {
    const target = e.target as HTMLInputElement;
    // 现在可以安全使用[name]更新表单状态
    setForm(prev => ({ ...prev, [name]: target.value }));
  };

  return <input type="text" name={name} value={value} onChange={handleChange} />;
}

4. 父组件中使用子组件

直接传递类型匹配的setForm和对应字段值即可:

function LoginForm() {
  const [form, setForm] = createSignal<FormState>({
    username: '',
    password: ''
  });

  return (
    <form>
      <InputText name="username" value={form().username} setForm={setForm} />
      <InputText name="password" value={form().password} setForm={setForm} />
      // 支持添加自定义字段,比如email
      <InputText name="email" value={form().email || ''} setForm={setForm} />
    </form>
  );
}

更安全的可选方案(限制键为已有字段)

如果不需要支持任意新增字段,只想用[name]更新已有字段,可以用keyof约束name的类型,避免拼写错误:

type InputTextProps<T> = {
  name: keyof T;
  value: string;
  setForm: Setter<T>;
};

function InputText<T extends Record<string, string>>({ name, value, setForm }: InputTextProps<T>) {
  const handleChange = (e: Event) => {
    const target = e.target as HTMLInputElement;
    setForm(prev => ({ ...prev, [name]: target.value }));
  };

  return <input type="text" name={name as string} value={value} onChange={handleChange} />;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:05:21