Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
이 에러는 string literal 타입만이 허용되는 곳에 string 타입을 사용했기 때문이라고 하는데..
이게 대체 무슨 말일까?
const helloWorld1 = "Hello World" // 1. 'Hello World' 타입 => Hello World라는 타입만 허용
let helloWorld2 = "Hello World" // 2. string 타입 => string 타입만 허용
const helloWorld3: string = "Hello World" // 3. string 타입 => string 타입만 허용
b 변수는 let으로 선언되어 재할당될 수 있을 경우 어떤 문자열이든 넣을 수 있으며 그 경우의 수가 무한대이다. 그렇기 때문에 컴파일러는 이 변수를 string 타입으로 추론한다. 그리고 c 변수는 명시적으로 string 타입으로 선언했으므로 그냥 string 타입이다.
하지만 a의 경우는 조금 이야기가 달라진다. 컴파일러는 이 변수를 string이 아닌 조금 더 좁은 타입(narrowed type)으로 선언한 것으로 추론한다. 이 것을 Literal Narrowing이라고 한다. (참고로 타입 추론은 TypeScript 컴파일러가 제공하는 뛰어난 기능 중 하나이며, 개발자가 명시적으로 타입을 선언해 주지 않을 경우 컴파일러가 할당되는 값을 기준으로 타입을 스스로 결정하는 것을 말한다.)
따라서 a의 타입은 string이 아니라 string타입을 좁혀 만든 string literal type이다. 여기서 "타입을 좁힌다"는 말의 의미는 무한대의 경우의 수를 가질 수 있는 string타입보다 훨씬 구체적인 string의 부분집합, "Hello World"만을 허용하는 타입을 선언했다는 뜻이다.
따라서 아래와 같이 명시적으로 literal type을 선언하면 let으로 선언된 변수도 "Hellow World" 타입만을 허용하도록 만들 수도 있다.
출처 : https://soopdop.github.io/2020/12/01/index-signatures-in-typescript/
https://soopdop.github.io/2020/12/01/index-signatures-in-typescript/
여기서 너무 설명을 잘해줘서.. 따로 할게 없는듯
짧게 말하면
1. 변수가 const이기 때문에 1은 평생 'Hello World'만 찍어야 한다. = 타입이 'Hello World' 자체가 된다
2. 변수가 let 이기 때문에 string이라는 것만 알고 내용은 바뀔 수 있다 = 타입이 string이 된다
2. 변수가 const이지만 : string 으로 string이라는 것을 명시했다 = 타입이 string이 된다
interface IChoicedCandidate {
a: number;
b: number;
c: number;
d: number;
e: number;
}
const maxCandidate = Object.keys(ChoicedCandidate).filter((key: string) => {
return ChoicedCandidate[key] === maxVoted;
});
// Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'IChoicedCandidate'.
// No index signature with a parameter of type 'string' was found on type 'IChoicedCandidate'.
"No index signature with a parameter of type 'string' was found on type 'IChoicedCandidate'."
에서 왜 문제가 생겼는지 알 수 있다.
내가 전달한 key에서 string을 찾을 수 없다고 함.
.
.
.
!!틀린 코드
그래서 string을 하나하나 넣어주려 했는데
interface IChoicedCandidate {
[a: string]: number;
[b: string]: number;
[c: string]: number;
[d: string]: number;
[e: string]: number;
}
또 오류가 생겼다
'Duplicate index signature'
index signature가 중복되었다는 말.
그래서 알아봄
interface IChoicedCandidate {
[index: string]: number; // 이렇게 한 줄만 써주면 된다
a: number;
b: number;
c: number;
d: number;
e: number;
}
각 key에 타입을 계속 지정해줄 필요는 없고
index 하나에 key 타입과 value 타입을 지정해주면 된다.
* 꼭 index를 이용할 필요는 없음
'✍ 공부' 카테고리의 다른 글
[ Javascript / React / typescript]객체 value값으로 key 값 찾기. (0) | 2022.02.28 |
---|---|
[react] .process.env.REACT_APP_KEY undefined (0) | 2021.12.09 |