티스토리 뷰
주요 개발 환경
- Next.js 13.4.19
- TypeScript
- Emotion
Error message
- Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ default: string; danger: string; outline: string; }'.
- No index signature with a parameter of type 'string' was found on type '{ default: string; danger: string; outline: string; }'.ts(7053)
배경
- Next.js + Typescript 를 기반으로 개발 환경을 구성하였고 CSS-in-JS 라이브러리로 Emotion을 사용하고 있습니다.
interface StyledProps {
size: string;
variant: string;
}
const colors = {
default: 'rgb(36, 41, 47)',
danger: 'rgb(207, 34, 46)',
outline: 'rgb(9, 105, 218)',
};
const sizeStyles = {
sm: {
fontSize: '1.2rem',
padding: '3px 12px',
},
md: {
fontSize: '1.4rem',
padding: '5px 16px',
},
lg: {
fontSize: '1.6rem',
padding: '9px 20px',
},
};
- 버튼의 색상과 폰트를 여러가지로 주기 위해 조건을 설정하였고
<S.Button variant="outline" size="md">
완료
</S.Button>
- 위와 같이 버튼에 props를 넘겨주어서 조건부 스타일링을 하려고 하였는데요!
- 각각 선언한 변수를 인덱스 시그니쳐로 참조하려고 할 때 타입 에러가 발생해서 타입을 명시해주려다 학습한 내용을 정리하게 되었습니다.
인덱스 시그니쳐(Index Signature)
// 문자열로 참조
let foo = {};
foo['hello'] = 'world';
// 객체로 참조
foo[obj] = 'world';
console.log(foo['hello']); // world
console.log(foo[obj]); // world, toString() 호출
- 자바스크립트에서는 객체의 프로퍼티를 참조할 때 문자열와 객체로 액세스가 가능합니다. 이 때 객체로 참조할 때는 런타임시 객체의 toString() 메소드를 호출하게 됩니다.
- 타입스크립트에서는 인덱스 시그니처를 사용할 때 고려해야 할 부분이 조금 더 있습니다.
const obj = {
foo: "hello",
}
let propertyName = "foo"
console.log(obj[propertyName]) // compile error!
- 자바스크립트에서는 허용되지만 타입스크립트에서 에러가 발생하는 이유는 string literal 타입만 허용되는 곳에 string 타입을 사용했기 때문입니다.
const a = "Hello World"
let b = "Hello World"
const c: string = "Hello World"
- 이 경우 b는 let으로 선언이 되었기 때문에 어떤 문자열이든 재할당될 수 있습니다. 따라서 컴파일러는 이것을 string 타입으로 추론합니다.
- c는 타입을 명시했기 때문에 string 타입이 됩니다.
- 그러나 a는 string 타입이 아니라 더 좁은 타입으로 추론합니다. 이것을 Literal Narrowing 이라고 하는데요. 무한대의 경우의 수를 가진 string이 아니라 더 구체적인 타입인 string literal type으로 생각하는 것입니다.
타입스크립트에서 인덱스 시그니쳐 사용하기
- 우선 인덱스 시그니쳐의 key 타입은 string, number, symbol, 그리고 template literal 가 가능합니다.
const colors: {[key: string]: string} = {
default: 'rgb(36, 41, 47)',
danger: 'rgb(207, 34, 46)',
outline: 'rgb(9, 105, 218)',
};
- 인덱스 시그니처의 타입을 지정할 때는 {[key : T] : U} 형식으로 사용합니다.
- 대괄호 안에 key의 타입, value의 타입을 적어주면 되는 것이죠!
const sizeStyles: { [key: string]: { [subKey: string]: string } } = {
sm: {
fontSize: '1.2rem',
padding: '3px 12px',
},
md: {
fontSize: '1.4rem',
padding: '5px 16px',
},
lg: {
fontSize: '1.6rem',
padding: '9px 20px',
},
};
- 위와 같은 중첩된 구조도 마찬가지겠죠?!
참고 자료
반응형
'개발냥이 > 타입스크립트(Typescript)' 카테고리의 다른 글
디바운싱(Debouncing)과 쓰로틀링(Throttling) 정리 (0) | 2023.08.19 |
---|---|
[리액트+타입스크립트] 프로젝트 리팩토링(refactoring)_사이드바(sidebar) (0) | 2023.07.31 |
[Next.js + 타입스크립트] 무한 스크롤(Infinite scroll) 구현해보기(feat. Intersection observer) (0) | 2023.07.15 |
[리액트+타입스크립트] 이미지 업로드 구현 & 이미지와 콘텐츠 하나의 객체로 관리하기 (0) | 2023.07.12 |
[Next.js + typescript] 페이지네이션(Pagination) 구현해보기 (0) | 2023.07.10 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Algorithm
- 이분탐색
- 자바bfs
- 스프링부트
- SQL
- JPA
- Spring
- 정렬
- BFS
- 자바
- CS
- 리액트
- java
- Queue
- DP
- 자바트리
- 자바dp
- 알고리즘
- 백준
- 해시맵
- Nest
- Comparator
- JavaScript
- SQLD
- 자바스크립트
- 스프링
- 형변환
- 타입스크립트
- 프로그래머스
- dfs
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함