React Typescript - 无法很好地建立对象类型

React Typescript - Can't stablish type of object well

我刚开始学习打字稿。我试图从 Javascript 迁移一个项目,但我被自定义挂钩卡住了。

挂钩 useForm 只是处理表单中输入的 onChange 事件,然后更新它们的值,这样我就可以写入并控制它们的状态。

interface formProps{
  initialValues: {[key: string]: string}
}

export const useForm = ( initialState: formProps['initialValues'] ) => {
  const [values, setValues] = useState(initialState);

  const reset = () => {
    setValues(initialState);
  }

  const handleInputChange = ({ target }: React.ChangeEvent<HTMLInputElement>) =>{
    setValues({
      ...values,
      [target.name]:target.value
    })
  }
  return [values, handleInputChange, reset]
}

useForm 的参数应该是一个具有不同条目的对象,但问题是它可能随时不同,所以我不能指定它。

当我尝试在组件中使用挂钩时,例如 values.userIDvalues['password`] 我收到错误:

The property 'password' does not exist on type '{ [key: string]: string; } | (({ target }: ChangeEvent) => void)'

我该如何解决这个问题?提前致谢!

编辑: 我使用以下方法从 'values' 中提取值:

const [values, handleInputChange] = useForm({userID: '', password: ''})

我会根据初始状态使用泛型来类型化状态,return一个对象,所以TS可以很容易地推断出类型(TS playground):

import React, { useState, ChangeEventHandler, ChangeEvent } from 'react';

export const useForm = <T extends Record<string, string>>( initialState: T ) => {
  const [values, setValues] = useState(initialState);

  const reset = () => {
    setValues(initialState);
  };

  const handleInputChange = ({ target }: ChangeEvent<HTMLInputElement>) => {
    setValues({
      ...values,
      [target.name]:target.value
    });
  };

  return { values, handleInputChange, reset };
}

const { values, handleInputChange } = useForm({ userID: '', password: '' });

values['userID'] = 'x';

values['password'] = 'y';

我使用了它:

import { useState } from "react";

interface InitialStateTypes  {
  [key: string]: string;
}

export const useForm = (initialState: InitialStateTypes): [InitialStateTypes, ({ target }: React.ChangeEvent<HTMLInputElement>) => void, ()=> void]  => {
  const [values, setValues] = useState(initialState);

  const reset = () => {
    setValues(initialState);
  }

  const handleInputChange = ({ target }: React.ChangeEvent<HTMLInputElement>) =>{
    setValues({
      ...values,
      [target.name]:target.value
    })
  }
  return [values, handleInputChange, reset]
}

而且我可以使用 values['value'] 而不是 values.value 访问 'values' 中的值。