I have created this codesandbox replicating my issue
- 1) I first created the component, (for styling and track if the input has content or not.
- 2) Everything works, but as need to add more forms to the project, i thought, damn maybe i could also created an useInput hook to just manage the value update instead of having to add
onChange: {e => {setSomething(e.target.value)}}
all the time.
So i created these useInput, but i got this annoying red linter errors. Its probably some basic type issue, but i can figure it out how to get rid of this issue. without any
type solutions
? Thanks in advance
Error screenshot and chunk of code below, but 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>
);
};
The problem came from the incorrectly inferred type of the returned value from the useInput hook. TS think that the type is
(string | onChangeType)[]
. That means thatstring
oronChangeType
can be at any position in the array, while you have very fixed order.要解决此问题,您需要提供一些帮助,然后像这样强制转换返回的数组
或明确指定useInput函数的返回类型