프로젝트를 하는 도중 컴포넌트 인터페이스 설정할때
useForm에 타입매개변수를 넣어주려했는데, 생각지 못한 부분에서 타입 에러가 났었다.
interface testProps{
A : useForm<A | B>
B : useForm<A> | useForm<B>
}
그래서 타입 매개변수안에 | 을 넣을때 A와 B의 경우 무슨 차이점이 있는지 자세히 알아보려 했다.
A , B가 다음과 같이 정의되어있다고 가정해 보자
interface A {
name: string;
age: number;
}
interface B {
email: string;
subscribed: boolean;
}
interface testProps {
A: useForm<A | B>;
B: useForm<A> | useForm<B>;
}
이 경우, useForm<A>는 name과 age 필드를 포함하는 폼을 관리하고, useForm<B>는 email과 subscribed 필드를 포함하는 폼을 관리한다.
여기서 A의 경우에는 폼이 A의 필드인 name, age 또는 B의 필드인 email, subscribed 혹은 두 인터페이스의 필드를 모두 가질 수 있다.
하지만 B의 경우에는 A의필드를 가지거나, B의 필드를 가질 수 있지만, 두 인터페이스의 필드를 동시에 가질 수는 없다.
useForm<A | B>:
이 경우에는 폼 데이터가 동적으로 A 또는 B 타입 중 하나로 결정될 때 유용하다,하지만 타입 안전성이 떠러질 수 있기에 타입 가드나 조건문 처리를 해줘야 한다.
예시코드)
interface A {
name: string;
age: number;
}
interface B {
email: string;
subscribed: boolean;
}
const MyComponent = () => {
const { control, setValue } = useForm<A | B>();
// 폼 데이터가 동적으로 A 또는 B 타입일 수 있음
const handleFormSubmit = (data: A | B) => {
if ('name' in data) {
console.log('A 타입 데이터:', data);
} else {
console.log('B 타입 데이터:', data);
}
};
return (
<form onSubmit={handleFormSubmit}>
{/* 폼 필드들 */}
</form>
);
};
useForm<A> | useForm<B>
이 경우에는 폼 데이터의 타입이 컴파일 타임에 결정되므로, 타입 안전성이 높지만 동적으로 타입이 결정되는 상황에서는 유연성이 떨어진다.
interface A {
name: string;
age: number;
}
interface B {
email: string;
subscribed: boolean;
}
const MyComponent = ({ isTypeA }: { isTypeA: boolean }) => {
const formA = useForm<A>();
const formB = useForm<B>();
// 특정 조건에 따라 useForm<A> 또는 useForm<B>를 선택적으로 사용
const { control, setValue } = isTypeA ? formA : formB;
const handleFormSubmit = (data: A | B) => {
if (isTypeA) {
console.log('A 타입 데이터:', data as A);
} else {
console.log('B 타입 데이터:', data as B);
}
};
return (
<form onSubmit={handleFormSubmit}>
{/* 폼 필드들 */}
</form>
);
};
두가지 타입선언의 차이점을 확인하고, 올바른 상황에 쓰도록 하자