문제 상황
문제 코드
//PokemonDetail.tsx
interface PokemonDetailProps {
pokemonData: TPokemon;
}
function PokemonDetail({ pokemonData }: PokemonDetailProps) {
...
return(
...
<DetailForm label="타입">
<ul className="flex flex-row gap-x-1">
{pokemonData.types.map((type, index) => (
<li key={index}>
<TypeChip
label={type.type.korean_name}
intent={type.type.intent} // Type 'string' is not assignable to type '"dark" | "fire" | "grass" | "electric" | ...
/>
</li>
))}
</ul>
</DetailForm>
)}
그 외 코드
//TypeChip.tsx
const typeChipVariants = cva(
"text-sm font-bold text-white border rounded-md px-4",
{
variants: {
intent: {
dark: "bg-[#775544]",
fire: "bg-orange-600",
grass: "bg-green-600",
electric: "bg-[#ffce6b]",
water: "bg-blue-600",
ground: "bg-yellow-800",
rock: "bg-[#ca8a04]",
fairy: "bg-[#FAA2C1]",
poison: "bg-[#BE4BDB]",
bug: "bg-[#65a30d]",
dragon: "bg-[#7e22ce]",
psychic: "bg-[#e879f9]",
flying: "bg-cyan-400",
fighting: "bg-[#dc2626]",
normal: "bg-[#a3a3a3]",
steel: "bg-[#94a3b8]",
ice: "bg-[#22d3ee]",
ghost: "bg-[#581c87]",
},
},
}
);
export type TypeChipVariantsType = VariantProps<typeof typeChipVariants>;
type TypeChipProps = {
label: string;
} & TypeChipVariantsType;
function TypeChip({ label, name }: TypeChipProps) {
return <div className={typeChipVariants({ name })}>{label}</div>;
}
export default TypeChip;
//pokemon.type.ts
export type TPokemon = {
id: number;
name: string;
korean_name: string;
height: number;
weight: number;
sprites: {
front_default: string;
other: {
"official-artwork": {
front_default: string;
};
};
};
types: {
type: {
name: string;
korean_name: string;
}
}[];
abilities: { ability: { name: string; korean_name: string } }[];
moves: { move: { name: string; korean_name: string } }[];
};
원인
type.type.intent (string Type)
와 TypeChipVariantsType ("dark" | "fire" | ...의 Union Type)
의 타입이 달라서 발생하는 문제였다.첫번째 문제 해결 방법
TPokemon
의 name에 TypeChipVariantsType
을 타입으로 지정해준다.TypeChipVariantsType
의 타입은 { intent: "dark" | "fire" | ... }
이므로 의도했던 "dark" | "fire" | ...
와는 다른 타입으로 인식되었다...두번째 문제 해결 방법
TypeChipVariantsType
의 intent 속성 안에는 Union Type을 가져오는 것이 목표이다.TPokemon
에서 name 속성에 Union Type이 필요하므로 intent 속성의 이름을 name으로 바꾸고 TypeChipVariantsType
을 type 객체와 합쳐준다.두번째 문제 해결 방법 코드
//TypeChip.tsx
const typeChipVariants = cva(
"text-sm font-bold text-white border rounded-md px-4",
{
variants: {
name: {
dark: "bg-[#775544]",
fire: "bg-orange-600",
grass: "bg-green-600",
electric: "bg-[#ffce6b]",
water: "bg-blue-600",
ground: "bg-yellow-800",
rock: "bg-[#ca8a04]",
fairy: "bg-[#FAA2C1]",
poison: "bg-[#BE4BDB]",
bug: "bg-[#65a30d]",
dragon: "bg-[#7e22ce]",
psychic: "bg-[#e879f9]",
flying: "bg-cyan-400",
fighting: "bg-[#dc2626]",
normal: "bg-[#a3a3a3]",
steel: "bg-[#94a3b8]",
ice: "bg-[#22d3ee]",
ghost: "bg-[#581c87]",
},
},
}
);
export type TypeChipVariantsType = VariantProps<typeof typeChipVariants>;
type TypeChipProps = {
label: string;
} & TypeChipVariantsType;
function TypeChip({ label, name }: TypeChipProps) {
return <div className={typeChipVariants({ name })}>{label}</div>;
}
export default TypeChip;
//pokemon.type.ts
export type TPokemon = {
id: number;
name: string;
korean_name: string;
height: number;
weight: number;
sprites: {
front_default: string;
other: {
"official-artwork": {
front_default: string;
};
};
};
types: {
type: {
korean_name: string;
} & TypeChipVariantsType
}[];
abilities: { ability: { name: string; korean_name: string } }[];
moves: { move: { name: string; korean_name: string } }[];
};
//PokemonDetail.tsx
interface PokemonDetailProps {
pokemonData: TPokemon;
}
function PokemonDetail({ pokemonData }: PokemonDetailProps) {
...
return(
...
<DetailForm label="타입">
<ul className="flex flex-row gap-x-1">
{pokemonData.types.map((type, index) => (
<li key={index}>
<TypeChip
label={type.type.korean_name}
name={type.type.name}
/>
</li>
))}
</ul>
</DetailForm>
)}