POTATO THAT WANT TO BE HUMAN

[Typescript] string key로 객체 접근하기 본문

FRONTEND/JavaScript

[Typescript] string key로 객체 접근하기

녜힝 2024. 2. 13. 15:40
반응형

자바스크립트에서는?

자바스크립트에서 key를 통해 객체에 접근하는 법은 다음과 같다.

const object = {
    red: "FF0000",
    green: "00FF00",
    blue: "0000FF"
};

console.log(object['red']);

 

그렇다면 타입스크립트에서는?

타입스크립트에서도 똑같다 

그런데 string key를 변수에 가둔다면 ?!

const object = {
    red: "FF0000",
    green: "00FF00",
    blue: "0000FF"
};
let name = 'red';

console.log(object[name]);
// Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{red: string; green: string; blue: string; }'. No index signature with a parameter of type 'string' was found on type '{red: string; green: string; blue: string; }'

 

다음과 같은 에러가 발생한다 

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

 

네..? 모라고요...?

간단히 보면 이 말이다.

'string' 유형의 표현식은 우리의 object 유형을 인덱스하는 데 사용할 수 없다 !

 

여기까지 기억해두고 다음 주제로 잠깐 넘어가보자

 

String과 String Literal

const A = "happytape";
let B = "happytape";
const C: string = "happytape";

B는 let 으로 선언되어 재할당 될 수 있을 경우 어떤 문자열이든 넣을 수 있다. 그렇기 때문에 컴파일러는 B를 string 타입으로 추론한다.

C는 명시적으로 string 타입으로 선언했으므로 컴파일러도 string타입으로 알게 된다.

그렇다면 A는?

A의 경우, const로 선언됐기 때문에 값의 변경이 일어나지 않기 때문에 타입스크립트에서는 이런 값에 대해 좀 더 엄격한 기준을 세우기를 바란다. 그렇기 때문에 컴파일러는 A의 타입을 string보다 좀 더 좁은 'happytape'인 string literal 타입으로 선언한 것으로 추론한다. 이러한 현상을 Literal Narrowing이라고 한다.

 

 

 

여기서 위에서 발생했던 에러를 떠올려 보자

'string' 유형의 표현식은 우리의 object 유형을 인덱스하는 데 사용할 수 없다 !

라고 했는데, String Literal 개념을 접목시키면 이해할 수 있다.

 

타입스크립트는 object 각각의 key를 전부 고유한 단일 타입으로 보고있기 때문에

string key를 인덱스로 사용할 수 없다는 의미였다.

 

그렇다면 어떻게 해결해야 할까?

 

Index Signature

해결법은 다음과 같이 타입에 Index Signature를 추가하는 것이다.

예시 코드를 보자.

type ObjectType = {
    [idx :string] :string
    red :string
    green :string
    blue :string
}

const object = {
	red: "FF0000",
    green: "00FF00",
    blue: "0000FF"
};

const name = "red";
console.log(object[name]);	//"FF0000"

객체에 대한 타입을 선언할 때 [idx :string] :string 을 추가해야 한다.

이렇게 되면 idx(key)에는 string타입이, value에는 string타입이 들어가야 함을 명시해줌으로써 string literal type이 추론되는 것을 방지하는 것이다.

 

 

참고 블로그

https://soopdop.github.io/2020/12/01/index-signatures-in-typescript/

반응형
Comments