返回一组对象和函数打字稿

时间:2021-01-25 18:20:10

标签: reactjs typescript react-hooks

首先,我面临的问题:

我用 vanilla JS 自制的 React Hook 工作了几个月,代码如下:

import { useState } from 'react';

const useForm = (initialValues) => {
    const [state, setState] = useState(initialValues);

    return [
        state,
        (e) => {
            if (typeof e.target !== 'undefined') {
                setState({
                    ...state,
                    [e.target.name]: e.target.value,
                });
            } else {
                setState({ ...e });
            }
        },
    ];
};

export default useForm;

现在,我决定使用 Typescript。但是无法转换那个钩子。除了返回接口/类型之外,我已经准备好了一切。相同的钩子打字稿版本(返回类型错误):

import { useState, FormEvent } from 'react';

interface ReturnProps {
  [index: number]: Record<string, unknown>;
  [index: number]: (e: FormEvent<HTMLInputElement>) => void;
}

const useForm = (initialValues: Record<string, unknown>): ReturnProps => {
  const [state, setState] = useState(initialValues);

  return [
    state,
    (e: FormEvent<HTMLInputElement>): void => {
      if (typeof e.currentTarget !== 'undefined') {
        setState({
          ...state,
          [e.currentTarget.name]: e.currentTarget.value,
        });
      } else {
        setState({ ...e });
      }
    },
  ];
};

export default useForm;

问题是:在这种情况下如何返回正确的类型?

1 个答案:

答案 0 :(得分:1)

您只需要修复 ReturnProps 类型:

interface ReturnProps {
  [index: number]: Record<string, unknown>;
  [index: number]: (e: FormEvent<HTMLInputElement>) => void;
}

不能有两个这样的重复索引签名。

由于返回数组中的第一个元素是 Record,第二个元素是回调,因此请改用元组:

type ReturnProps = [
    Record<string, unknown>,
    (e: FormEvent<HTMLInputElement>) => void
]

您甚至可以完全省略 ReturnProps,而 TS 仍然能够推断出正确的类型:

const useForm = (initialValues: Record<string, unknown>) => {

(在可能的情况下让 TS 自动推断类型可以真正减少可能分散脚本主要逻辑注意力的类型噪音。)