[Solved] string 타입을 key로 사용할 때 발행하는 에러 in Typescript : Index Signatures

0

TYPESCRIPT

목록 보기
6/8
post-thumbnail

혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다.

문제 상황

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ 4: string; 5: string; }'.
No index signature with a parameter of type 'string' was found on type '{ 4: string; 5: string; }'.

객체에 문자열로 된 변수를 key로 적용할 때 위와 같은 에러가 발생했다.

errorType[FirstErrorNumber]

  • errorType은 객체
  • FirstErrorNumber은 문자열 혹은 undefined로 정의
const errorType = { 4: "요청", 5: "서버" };
const FirstErrorNumber = action.error.message?.at(-3); // 에러코드 첫번째 숫자 추출 -> 4 : `Request failed with status code 404`

if (FirstErrorNumber) {
  console.log(`${errorType[FirstErrorNumber]}`); // error 발생
});
}

원인

Javascript와 달리 Typescript에서는 string과 literal(명확하게 정해진 값)을 구분한다.

보통 temp 처럼 타입추론으로 사용하면 타입이 문자열이 아닌 literal "name"으로 고정된 값으로 상수(?)처럼 고정된다. 반면 temp2 처럼 string 이라고 명시하면 그때 문자열 타입으로 지정된다.
객체 선언에서도 const errorType = { 4: "요청", 5: "서버" }; 로 타입추론이 되면 key는 4,5인 literal로 지정되어있다. literal 타입이 들어와야하는데 string 타입이 들어왔으므로 발생한 것이다.


해결 방법 : Index Signatures

Index Signatures를 이용하여 객체의 타입에서 key의 타입을 문자열로 명시한다.

Index Signatures

You can use an index signature to describe the types of possible values
...
Only some types are allowed for index signature properties: string, number, symbol, template string patterns, and union types consisting only of these.
typescript 공식문서

형태

const objSample: { [key : string] : 객체가_가지는_value타입 } = {key1: 객체가_가지는_value값}
/* 
[key: type] : valueType

타입추론 대신 객체의 타입을 명시해야한다.
interface나 직접 객체를 명시하여 key가 문자열임을 알려준다.
*/

적용 예시

// 적용한 코드 : 객체의 타입이므로 [key: 타입]을 사용
const errorType : { [key: string]: string } = { 4: "요청", 5: "서버" };
const FirstErrorNumber = action.error.message?.at(-3); 

if (FirstErrorNumber) {
  console.log(`${errorType[FirstErrorNumber]}`);
});
}
// interface로 타입을 명시하는 경우 : 아래의 예시는 배열이므로 [index: 타입]을 사용
interface StringArray {
  [index: number]: string;
}
const myArray: StringArray = getStringArray();
const secondItem = myArray[1];

참고

const str = 'name' as string; 처럼 구체적입 타입을 설명하는 Type assertions 방식으로도 해결 가능하지만 런타임 에러가 발생할 수 있으므로 추천하지 않는다고 한다.

When using them, we effectively tell TypeScript that value X will be of type Y and not to worry about it. This could cause runtime errors if we are wrong.
- Element implicitly has an 'any' type because expression of type 'string' can't be used to index type에서 발췌


TIL

Javascript에서 bracket notation obj[key] 에서 key에 toString() 이 자동으로 적용되는 것을 처음 알았다. 에러 해결하면서 여러가지 지식이 쌓인다.
Type Assertions 방식도 공식문서 보면서 의도를 알게되었다. 어떤 경우에 써야하는지 헷갈렸었는데. 타입이 여러가 사용될 수 있을 때 사용 할 수 있다는 것도. Typescript 어렵지만 보람은 있는 것같다.

0개의 댓글