React Typescript - 将道具传递给 Hooks 时出现类型错误

React Typescript - Type error between passing props to Hooks

我创建了this codesandbox replicating my issue

所以我创建了这些 useInput,但是我遇到了这个恼人的红色 linter 错误。它可能是一些基本类型的问题,但我可以弄清楚 如何解决这个问题。没有 any 类型的解决方案 ? 提前致谢

错误的屏幕截图和下面的代码块,但是 better test in the sandbox

#useInput.tsx

import { useState, ChangeEvent } from "react";

export type onChangeType = (event: ChangeEvent<HTMLInputElement>) => void;
const useInput = (initialValue = "") => {
  const [value, setValue] = useState(initialValue);

  const reset = () => setValue("");

  const onChange: onChangeType = e => {
    setValue(e.target.value);
  };

  return [value, onChange, reset];
};

export default useInput;

#Input.tsx

import React, { useState, ChangeEvent } from "react";
import styled, { css } from "styled-components";

import onChangeType from "./hooks/useInput";

interface iLabelProps {
  hasContent: boolean;
}

const hasContentCSS = () => css`
  border: 5px solid royalblue;
`;

const Label = styled.label<iLabelProps>```

interface iInput {
  readonly type?: string;
  readonly name: string;
  readonly label: string;
  value?: string | number | string[] | null;
  defaultValue?: string | number | string[] | null;
  readonly onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
}

export const Input = ({
  name = "email",
  label,
  value = null,
  defaultValue = null,
  onChange = null
}: iInput) => {
  const [hasContent, setHasContent] = useState(!!defaultValue);

  const onBlur = value => {
    setHasContent(value.length > 0);
  };

  return (
    <Label hasContent={hasContent}>
      <input
        type="text"
        name={name}
        {...defaultValue && { defaultValue: defaultValue }}
        {...!defaultValue && { value: value ? value : "" }}
        {...onChange && { onChange: onChange }}
        onBlur={e => onBlur(e.target.value)}
      />
      <span>{label}</span>
    </Label>
  );
};

问题来自 useInput 挂钩的 returned 值的错误推断类型。 TS认为类型是(string | onChangeType)[]。这意味着 stringonChangeType 可以位于数组中的任何位置,而您的顺序非常固定。

要解决此问题,您必须稍微帮助它,然后像这样 return 转换数组

return [value, onChange, reset] as [string, onChangeType, () => void];

或明确指定 useInput 函数的 return 类型

const useInput = (initialValue = ""): [string, onChangeType, () => void] => {...}