Javascript 如何设置event.target.value的类型?

Javascript 如何设置event.target.value的类型?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我有一个选择组件: type SelectProps = { title: string; name: string; items: string[]; onChange: (e: ChangeEvent<HTMLSelectElement>) => void; defValue: string; }; const Select: FC<SelectProps> = ({ title, name, items, onChange, defVal

我有一个选择组件:

type SelectProps = {
  title: string;
  name: string;
  items: string[];
  onChange: (e: ChangeEvent<HTMLSelectElement>) => void;
  defValue: string;
};

const Select: FC<SelectProps> = ({ title, name, items, onChange, defValue }) => {
  return (
    <>
      <label htmlFor={name}>
        {title}:
      </label>
      <select name={name} onChange={onChange} defaultValue={defValue}>
        {items.map((item) => (
          <option value={item} key={item}>
            {item}
          </option>
        ))}
      </select>
    </>
  );
};

解决这个问题的最好办法是什么

最快的方法是进行类型断言

假设这就是你初始化州的方式

type ThemeState = 'light' | 'dark';

const [theme, useTheme] = useState<ThemeState>('light');

这是一个不错的选择,但需要一点技巧

首先,让我们认识一下SelectProps中类型之间的关系:

这些项是字符串文本 在onChange中,事件的target.value将等于您的一项 defValue也应该是其中一项 要表达这些约束,我们需要使用通用接口

type SelectProps<T extends string> = {
  title: string;
  name: string;
  items: T[];
  onChange: (e: ChangeEvent<HTMLSelectElement> & { target: { value: T }}) => void;
  defValue: DeferTypeInference<T>;
};

const Select = function<T extends string>({ title, name, items, onChange, defValue }: SelectProps<T>) {
  return (
    <>
      <label htmlFor={name}>
        {title}:
      </label>
      <select name={name} onChange={onChange} defaultValue={defValue}>
        {items.map((item) => (
          <option value={item} key={item}>
            {item}
          </option>
        ))}
      </select>
    </>
  );
};
我们已经取得了一切成就

<Select
  title='Theme'
  defValue="light" // only "light" or "dark" are accepted
  name='theme'
  items={['light', 'dark']}
  onChange={event => event.target.value} // event.target.value is "light" or "dark"
/>

请注意使用了一个名为DeferTypeInference的类型。如果您想知道它为什么会在那里,请查看。

您可以建议将typescript const theme=e.target.value设置为light | dark;如何在组件上定义主题状态?我正在从reduxSo传递它setTheme是来自redux存储的动作分派?是export const setTheme=theme:'light'|'dark':ActionTypes=>{return{type:SET_theme,theme,};};我知道这种方法,但对我来说似乎是一种变通方法。这是正确的方法吗?据我所知不是。但我建议您将“SelectProps”下的项目设置为更安全的类型,这样它就不会接受任何随机字符串。你可以考虑把它改成这个项目:
const theme = e.target.value as ThemeState;
type SelectProps<T extends string> = {
  title: string;
  name: string;
  items: T[];
  onChange: (e: ChangeEvent<HTMLSelectElement> & { target: { value: T }}) => void;
  defValue: DeferTypeInference<T>;
};

const Select = function<T extends string>({ title, name, items, onChange, defValue }: SelectProps<T>) {
  return (
    <>
      <label htmlFor={name}>
        {title}:
      </label>
      <select name={name} onChange={onChange} defaultValue={defValue}>
        {items.map((item) => (
          <option value={item} key={item}>
            {item}
          </option>
        ))}
      </select>
    </>
  );
};
<Select
  title='Theme'
  defValue="light" // only "light" or "dark" are accepted
  name='theme'
  items={['light', 'dark']}
  onChange={event => event.target.value} // event.target.value is "light" or "dark"
/>