Element implicitly has an 'any' type because expression of type 'string' can't be used to index type

2024. 3. 27. 23:51· Typescript
목차
  1. 1. 인덱스 시그니처 추가 
  2. 2. 타입 어설션 (Type Assertion)
  3. 결론
728x90

객체에 동적 변수를 key 값으로 하여 접근하기 위해 대괄호 표기법을 사용했을 때, 이러한 타입 에러가 발생했다.

 

 

실제 코드는 훨씬 복잡하기 때문에 간략한 예시로 정리

const obj = {
  one: "uno",
  two: "dos",
  three: "tres",
};

for (const k in obj) {
  const v = obj[k];
}

 

obj에 명시된 타입이 없기 때문에 엘리멘트는 암시적으로 'any' 타입이다. 

 

에러 발생 상황

 

k의 타입은 string인 반면, obj 객체에는 ‘one’, ‘two’, ‘three’ 세 개의 키만 존재한다.

k와 obj 객체의 키 타입이 서로 다르게 추론되어 오류가 발생한 것이다.

 

이 오류를 해결하기 위해서는 k의 타입을 더욱 구체적으로 명시해야 한다.

 

이때 두가지 방법이 있다.

 

 


1. 인덱스 시그니처 추가 

interface Obj {
  [key: string] : string
}

const obj: Obj = {
  one: "uno",
  two: "dos",
  three: "tres",
};

for (const k in obj) {
  const v = obj[k];
}

 

key에 대한 타입도 명시를 해줌으로써 해결

 

근데 이 방법으로 해결이 되지 않는 경우가 있다.

 


2. 타입 어설션 (Type Assertion)

이때 사용할 수 있는 것이 keyof 이다.

 

Documentation - Keyof Type Operator

타입 컨텍스트에서 keyof 연산자 사용하기

www.typescriptlang.org

keyof 타입 연산자는 객체 타입에서 객체의 키 값들을 숫자나 문자열 리터럴 유니언을 생성한다.

 

let k: keyof typeof obj;
for (k in obj) {
  console.log(k);
}
// one
// two
// three

(사실 타입 정의 안해줘도 출력 값은 똑같다. 타입 에러가 날 뿐..)

 

 

keyof typeof obj는 obj의 key 값들로 구성된 문자열 리터럴 유니언을 생성하고, k의 타입이 그것임을 명시해준 것이다.

결과적으로 k는 타입을 명시해줌으로써 타입 안정성이 생겼다.

 

const obj = {
  one: "uno",
  two: "dos",
  three: "tres",
};

for (const k in obj) {
  const v = obj[k as keyof typeof obj];
}

 

 

 

그렇다면 첫 번째 코드에서 k 타입이 string으로 추론된 이유는?

▶ 타입스크립트에서 for ... in 루프를 사용하여 객체의 프로퍼티를 순회할 때, 루프 변수에 대한 타입 추론은 현재 존재하는 프로퍼티 키 뿐만 아니라 객체가 가질 수 있는 모든 프로퍼티 키를 고려한다. 그렇기 때문에 그 가능성의 합집합인 string 타입으로 k의 타입을 추론하는 것이다.

 


 

결론

아무런 처리를 해주지 않아도 타입스크립트는 k의 타입을 string으로 추론해주기 때문에 동작은 문제없이 된다.

하지만 타입 안정성을 위해 명확한 타입을 지정해주라는 타입 경고가 나오는 것이다.

 

 

 

 


[ 참고 자료 ] 

댄 밴더캄, 『 이펙티브 타입스크립트 』 : 아이템54 객체를 순회하는 노하우

타입스크립트 에러) Element implicitly has an 'any' type because expression of type 'string' can't be used to index type / indexable 타입

Typescript | JS는 정말 좋은 아이였구나(feat. Indexable)

728x90

'Typescript' 카테고리의 다른 글

Typescript 제네릭(generic)이란?  (0) 2024.09.26
인덱스 시그니처  (0) 2024.05.14
Type of emit value is always 'any' with new style defineEmits  (0) 2024.03.27
Typescript 인터페이스 네이밍 규칙 어떻게 할까? | 접두사 I를 사용하면 안 되는 이유  (1) 2024.03.27
@input event의 타입  (0) 2024.03.27
  1. 1. 인덱스 시그니처 추가 
  2. 2. 타입 어설션 (Type Assertion)
  3. 결론
'Typescript' 카테고리의 다른 글
  • Typescript 제네릭(generic)이란?
  • 인덱스 시그니처
  • Type of emit value is always 'any' with new style defineEmits
  • Typescript 인터페이스 네이밍 규칙 어떻게 할까? | 접두사 I를 사용하면 안 되는 이유
ZoD
ZoD
바쁘게 굴러가는 ZoD의 하루~
como siempre바쁘게 굴러가는 ZoD의 하루~
ZoD
como siempre
ZoD
  • 분류 전체보기 (173)
    • Daily (0)
    • Javascript (16)
      • 모던 자바스크립트 (46)
    • Typescript (8)
    • FrontEnd (7)
    • React (21)
      • tanstack query (1)
      • 라이브러리 (3)
    • Vue (33)
      • Nuxt (11)
      • Quasar (6)
    • CSS (12)
    • Storybook (8)
    • Figma (3)
    • CS 지식 (5)
    • Network (5)
    • 알고리즘 (2)
    • 사이드 프로젝트 (4)
      • ddangkong (4)
      • boncierge (0)
    • 개발, 근데 이제 헛소리를 곁들인 (1)
    • ETC (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.v4.2.2
ZoD
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.