反应打字稿-将道具传递到挂钩之间的类型错误

时间:2020-05-09 09:20:10

标签: reactjs typescript react-hooks typescript-typings react-props

我已经创建了this codesandbox replicating my issue

  • 1)我首先创建了<Input>组件,(用于样式和跟踪输入内容是否包含内容。
  • 2)一切正常,但是我认为需要向项目中添加更多表单,该死,也许我还可以创建一个useInput钩子来管理值更新,而不必一直添加onChange: {e => {setSomething(e.target.value)}}

所以我创建了这些useInput,但是却遇到了这个令人讨厌的红色短绒毛毛虫错误。它可能是一些基本的类型问题,但是我可以弄清楚如何摆脱这个问题。没有any类型的解决方案 ?预先感谢

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

enter image description here

#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>
  );
};

1 个答案:

答案 0 :(得分:1)

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

要解决此问题,您需要提供一些帮助,然后强制转换返回的数组

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

或明确指定useInput函数的返回类型

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