1. (TS 2345) Argument of type '...' is not assignable to parameter of type '...'
문제 상황:
광역시/도를 선택하면 해당 시/도에 대한 시/군/구를 select box에 보여줄 수 있게 하는 코드를 작성하려고 했다. 예를 들어 서울을 선택하면 서울의 코드 11000 중 앞의 두 자리 11을 divisionSelectValue라는 상태에 담고, 해당 상태를 useEffect의 종속성 배열에 넣어서 사용자가 시/도 단위의 지역을 선택해서 상태 변경이 일어날 때마다 districtList에 해당 시/도에 대한 시/군/구 데이터를 담으려는 게 목적이었다.
// divisions.ts 파일 예시
export const DIVISIONS_DATA = [
// { code: '0', name: '전국', districts: [] }
{
code: '11000',
name: '서울',
districts: [
{ name: '강남구', code: '11680' },
{ name: '강동구', code: '11740' },
{ name: '강북구', code: '113050' },
{ name: '강서구', code: '11500' },
{ name: '관악구', code: '11620' },
{ name: '광진구', code: '112150' },
{ name: '구로구', code: '11530' },
{ name: '금천구', code: '115450' },
{ name: '노원구', code: '11350' },
{ name: '도봉구', code: '11320' },
{ name: '동대문구', code: '11200' },
{ name: '동작구', code: '11590' },
{ name: '마포구', code: '11440' },
{ name: '서대문구', code: '11410' },
{ name: '서초구', code: '11650' },
{ name: '성동구', code: '11230' },
{ name: '성북구', code: '11290' },
{ name: '송파구', code: '11710' },
{ name: '양천구', code: '11470' },
{ name: '영등포구', code: '11560' },
{ name: '용산구', code: '11170' },
{ name: '은평구', code: '11380' },
{ name: '종로구', code: '11110' },
{ name: '중구', code: '11140' },
{ name: '중랑구', code: '11260' }
]
},
// 이하 생략
]
interface DistrictType {
code: string;
name: string;
}
// division: 지역 1단계 (광역시/도)
// district: 지역 2단계 (시/군/구)
const [divisionSelectValue, setDivisionSelectValue] = useState('');
const [districtSelectValue, setDistrictSelectValue] = useState('');
const [districtList, setDistrictList] = useState<DistrictType[]>([]);
useEffect(() => {
if (divisionSelectValue) {
setDistrictList(
DIVISIONS_DATA.find((d) => d.code.startsWith(divisionSelectValue))?.districts
);
}
}, [divisionSelectValue]);
에러 메시지:
Argument of type '{ name: string; code: string; }[] | undefined' is not assignable to parameter of type 'SetStateAction<DistrictType[]>'.
Type 'undefined' is not assignalbe to type 'SetStateAction<DistrictType[]>.'
에러 원인:
find 메소드를 사용하면 값을 못 찾아서 undefined가 나올 수 있는데, districtList의 타입은 DistrictType[]으로 정해져 있기 때문에 발생한 에러
해결책:
undefined가 나오지 않을 경우, 즉 find 메소드를 돌린 결과의 값이 있을 경우에만 setState 함수에 넣어주게끔 코드 수정
const [districtList, setDistrictList] = useState<DistrictType[]>([]);
useEffect(() => {
if (divisionSelectValue) {
const districts = DIVISIONS_DATA.find((d) =>
d.code.startsWith(divisionSelectValue)
)?.districts;
if (districts) setDistrictList(districts);
}
}, [divisionSelectValue]);
참고:
find 메소드처럼 undefined가 나올 수 있는 경우 뿐 아니라 document.querySelector 처럼 null 이 나올 가능성이 있는 메소드에서도 마찬가지 에러가 발생한다.
2. (TS 2749) refers to a value, but is being used as a type here
문제 상황:
styled components 로 작성한 공통 버튼 스타일 컴포넌트를 배경색, width 값 등을 조정할 수 있고, onClick 함수도 props로 받을 수 있는 등 보다 확장성 있는 공통 UI 컴포넌트로 수정하고자 했다.
// 수정 전
export const S_Button = styled.button`
color: var(--white);
background-color: var(--blue300);
:hover {
background-color: var(--blue200);
}
`;
// 수정 후
const StyledButton = styled.button<ButtonStyleType>`
width: ${(props) => props.width || '100%'};
background-color: ${(props) => props.backgroundColor || 'var(--blue300)'};
color: ${(props) => props.color || 'var(--white)'};
height: 50px;
padding: 10px 12px;
border-radius: 5px;
font-size: 1rem;
:hover {
background-color: ${(props) => props.hoverBgColor || 'var(--blue200)'};
}
`;
interface ButtonStyleType {
width?: string;
color?: string;
backgroundColor?: string;
hoverBgColor?: string;
}
interface S_ButtonProps {
children: string;
addStyle?: ButtonStyleType;
onClick?: () => void;
}
export function S_Button({ children, addStyle, onClick }: S_ButtonProps) {
if (addStyle) {
const { width, backgroundColor, color, hoverBgColor } = addStyle;
return (
<StyledButton
width={width}
backgroundColor={backgroundColor}
color={color}
hoverBgColor={hoverBgColor}
onClick={onClick}
>
{children}
</StyledButton>
);
} else if (onClick !== undefined) {
return <StyledButton onClick={onClick}>{children}</StyledButton>;
}
return <StyledButton>{children}</StyledButton>;
}
에러 메시지:
(TS2749) refers to a value, but is being used as a type here
에러 원인:
파일명이 .ts 였다. 스타일 컴포넌트만 있었을 때는 괜찮았지만, JSX를 리턴하는 리액트 컴포넌트를 .ts 파일에 작성하자 해당 오류가 발생하였다.
해결책:
확장자를 .ts 에서 .tsx로 변경
'돌멩이 하나 > 에러는 미래의 연봉' 카테고리의 다른 글
[기능 구현 챌린지] 무한 스크롤 UI (0) | 2023.05.30 |
---|---|
유틸리티 함수(비밀번호 유효성 검사) 및 테스트 코드 작성 (0) | 2023.04.07 |
netlify 자동 배포 설정 오류 해결 (0) | 2023.02.14 |
코드에 GitHub access token이 포함된 상태로 commit을 하면 어떻게 될까 (0) | 2023.01.31 |
[React] useEffect hook에서 async/await 쓰는 방법 (0) | 2023.01.09 |