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

TypeScript中如何为React状态指定仅含单个TLang键的对象类型?

React useState类型定义优化:仅保留单个语言键

问题代码

type TLang = 'tur' | 'eng';
const [filterState, setFilterState] = useState<{
  [key in TLang]: string | null;
}>(null);

const inputChangeHadnler =
  (type: TLang): React.ChangeEventHandler<HTMLInputElement> =>
  (event) => {
    setFilterState({ [type]: event.target.value });
  };

return <input onChange={inputChangeHadnler('tur')}></input>

报错信息

Argument of type '{ [x: string]: string; }' is not assignable to parameter of type 'SetStateAction<{ tur: string; eng: string; }>'.
Type '{ [x: string]: string; }' is missing the following properties from type '{ tur: string; eng: string; }': tur, engts(2345)

当前filterState的类型要求必须同时包含tur和eng两个属性,但实际需求是让它仅包含TLang中的单个键(要么tur,要么eng,或者null)。手动枚举{ tur: string | null } | { eng: string | null} | null的写法在语言数量增多时会变得繁琐,需要更通用的方案。

解决方案

可以用TypeScript的映射类型+索引访问生成通用的单键对象联合类型,无需手动枚举每个语言:

  1. 先定义通用的单键对象类型与最终状态类型:
// 单个语言键对应的对象类型
type SingleLangFilter<K extends string> = { [key in K]: string | null };
// 自动生成所有单键对象的联合类型,再加上null
type FilterStateType = { [K in TLang]: SingleLangFilter<K> }[TLang] | null;
  1. 修改useState的类型定义:
const [filterState, setFilterState] = useState<FilterStateType>(null);
  1. 调整事件处理器,让TS正确推断类型:
const inputChangeHadnler =
  <K extends TLang>(type: K): React.ChangeEventHandler<HTMLInputElement> =>
  (event) => {
    setFilterState({ [type]: event.target.value } as SingleLangFilter<K>);
  };

修改后的完整代码

import { useState } from 'react';

type TLang = 'tur' | 'eng';
type SingleLangFilter<K extends string> = { [key in K]: string | null };
type FilterStateType = { [K in TLang]: SingleLangFilter<K> }[TLang] | null;

const MyComponent = () => {
  const [filterState, setFilterState] = useState<FilterStateType>(null);

  const inputChangeHadnler =
    <K extends TLang>(type: K): React.ChangeEventHandler<HTMLInputElement> =>
    (event) => {
      setFilterState({ [type]: event.target.value } as SingleLangFilter<K>);
    };

  return <input onChange={inputChangeHadnler('tur')} />;
};

export default MyComponent;

这样无论TLang新增多少个语言值(比如加上'spa'),FilterStateType都会自动生成对应的单键对象联合类型,完全无需手动修改类型定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:06:00