이 연습에서는 매우 일반적인 패턴을 살펴보겠습니다.
여기서는 ComponentProps
를 가져와서 Input
컴포넌트에서 사용하겠습니다.
import { ComponentProps } from "react";
import { Equal, Expect } from "../helpers/type-utils";
export const Input = (
props: ComponentProps<"input"> & { onChange: (value: string) => void }
) => {
return (
<input
{...props}
onChange={(e) => {
props.onChange(e.target.value);
}}
></input>
);
};
Input
에는 기본적으로 React.ChangeEvent
를 포함한 전체 이벤트 객체와 함께 e.dafaultPrevented
, eventPhase
등을 제공하는 onChange
가 있습니다.
종종 우리는 이 모든 것을 원하지 않습니다.
예를 들어 새 값을 전달하거나 일부 네이티브 엘리먼트만 변경하고 싶다고 가정해 보겠습니다.
Input
은 다음과 같이 보일 수 있습니다.
export const Input = (
props: ComponentProps<"input"> & { onChange: (value: string) => void }
) => {
...
컴포넌트 내부에서는 모든 것이 정상적으로 보이지만 막상 사용하려고 하면 예상대로 작동하지 않습니다.
부모 컴포넌트 아래에서 테스트에서 오류를 확인할 수 있습니다.
const Parent = () => {
return (
<Input
onChange={(e) => {
console.log(e);
// error below!
type test = Expect<Equal<typeof e, string>>;
}}
></Input>
);
};
e
는 단순한 문자열이 아니라는 것을 보여줍니다. 대신 문자열 또는 React.ChangeEvent<HTMLInputElement>
로 타입되어집니다.
뭔가 잘못되고 있습니다.
Input
컴포넌트의 현재 구현에서, onChange가 실제로 ComponentProps<”input”>
에서 props를 재정의 하거나 제거하지 않았습니다.