reactjs - Typescript React: 기본 HTML 입력 요소 속성 prop 타입을 재정의하는 방법
저는 커스텀 'Input' 컴포넌트를 만들고 기본 HTML 입력 속성(props)을 확장하려고 하고 있습니다.
하지만 저는 또한 Typescript의 Omit을 사용하여 제 자신의 인터페이스 정의 내에서 기본 'size' 속성을 재정의하려고 시도하고 있지만, 작동하지 않는 것 같습니다.
(저는 또한 Typescript의 Pick/Exclude와 커스텀 Override 타입을 시도했지만, 동일한 오류가 발생했습니다...)
제가 이미 시도해본 비슷한 글:
- TypeScript에서 인터페이스의 속성을 재정의하기
- React 타입을 확장하여 HTML 속성을 props로 지원하는 방법
import React from 'react';
type A = React.HTMLAttributes<HTMLInputElement>;
interface InputProps extends Omit<A, 'size'> {
size?: 'sm' | 'md' | 'lg';
}
const Input = (props: InputProps) => {
return <input {...props} />;
};
TS 오류
(property) JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
Type '{ size?: "sm" | "md" | "lg"; defaultChecked?: boolean; defaultValue?: string | number | readonly string[]; suppressContentEditableWarning?: boolean; ... 250 more ...; onTransitionEndCapture?: (event: TransitionEvent<...>) => void; }' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
Type '{ size?: "sm" | "md" | "lg"; defaultChecked?: boolean; defaultValue?: string | number | readonly string[]; suppressContentEditableWarning?: boolean; ... 250 more ...; onTransitionEndCapture?: (event: TransitionEvent<...>) => void; }' is not assignable to type 'InputHTMLAttributes<HTMLInputElement>'.
Types of property 'size' are incompatible.
Type 'string' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.ts(2322)
답변 #1
interface InputProps....를(을) 교체하세요
type InputProps = {
size?: 'sm' | 'md' | 'lg';
} & Omit<A, 'size'>;
OP의 댓글을 기반으로,
const Input = ({ size, ...props }: InputProps) => {
// if(size) do something...
return <input {...props} />;
};
답변 #2
여기에서 설계상의 결함은 당신이 커스텀 Input 컴포넌트에 받아들이는 props에 있는 것이 아닙니다. 문제는 이미 size 속성이 예상되는 size 속성과 다르다는 것을 알고 있으면서도, 그 동일한 props를 HTML input 컴포넌트로 전달하고 있다는 점입니다. 이것이 바로 당신이 여기에 붙여넣은 오류에 반영된 내용입니다.
당신은 @silent가 설명한 대로 타입 정의를 수정할 필요가 있습니다.
하지만 그렇게 한 후에는, Input 컴포넌트 내부에서 사용자 정의 size 문자열을 input에 전달하기 전에 숫자로 매핑하는 작업을 해야 합니다.
편집:
댓글을 기반으로, 이것들이 CSS 클래스 이름이라고 말씀하셨습니다. 따라서 이것들은 size 속성이 아니라 className 속성에서 input 컴포넌트로 전달되어야 합니다.
// sets default size to 'md' - you can change or remove this
const Input = ({size = 'md', className, ...props}: InputProps) => {
// combine with existing class names
const newClass = className + ' ' + size; // could trim redundant spaces but don't need to
return (
<input
{...props}
className={newClass}
/>;
};
당신은 size에 아무것도 전달할 필요가 없습니다. 사실 이 컴포넌트는 input의 size 속성에 아무것도 설정할 수 없습니다. 왜냐하면 우리가 스프레드 연산자({size='md', className, ...props})를 사용할 때 size를 제거했기 때문입니다. ...props는 '나머지(rest)' 매개변수로, 다른 방식으로 추출되지 않은 모든 속성을 포함하므로, InputProps에서 size나 className을 포함하지 않습니다.
