타입스크립트를 이용해 새로운 프로젝트를 진행하던 어느날
처음 보는 에러를 마주쳤습니다.
element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ duelist: boolean; recon: boolean; sentinels: boolean; controllers: boolean; nodicision: boolean; }'. no index signature with a parameter of type 'string' was found on type '{ duelist: boolean; recon: boolean; sentinels: boolean; controllers: boolean; nodicision: boolean; }'
이 에러는 Typescript에서 객체의 프로퍼티에 문자열을 이용해 인덱싱을 시도했을때 발생하는 에러이다.
Typescript에서는 문자열로 접근하게되면 프로퍼티의 이름 뿐만 아닌 다른 모든 값을 갖을 수 있기 때문이다.
일반 Javascript에서는 객체의 프로퍼티에 접근할때 브라켓 표기법 혹은 점 표기법을 사용해도 문제 없이 접근 가능하지만, Typescript의 경우는 점 표기법은 가능하지만 브라켓 표기법으로 접근하면 위와 같은 에러가 발생하는 경우도 있다.
const [selectedState, setSelectedState] = useState<selectedStateInterface>({
position: {
duelist: false,
recon: false,
sentinels: false,
controllers: false,
noDicision: false,
},
...
});
나의 경우는 위와 같은 상태에 변화를 주려할때 에러가 발생했다.
const selectPosition = (ePosition: string) => {
...
else if (selected.position.length < 2 && existIdx === -1) {
...
setSelectedState({
position: { ...selectedState.position, [ePosition]: true },
operator: [...positionImg[ePosition]]
});
}
...
};
위의 코드에서 [ePosition]: true 부분에서 에러가 발생하는 것이다.
점 표기법을 이용하면 되지만, 위와 같이 인자로 전달된 문자열 타입으로 프로퍼티에 접근할 때는 브라켓 표기법을 이용해야 했다.
그랗다면, 이처럼 점 표기법이 안되는 상황이며 브라캣 표기법을 사용했을때 맨위의 에러가 발생했다면 어떻게 해야할까?
이 상황에서는 타입을 지정할 때 아래와 같이 타입을 지정하면 해결된다.
export interface selectedStateInterface {
position: {
[key: string]: boolean,
},
operator: ImgInterface[]
}
Typescript에서 문자열이 프로퍼티 이름이 아닌 모든 값이 될 수 있음을 방지하고자 인덱스 서명을 추가해줘야한다.
위의 코드에서는 [key: string]: boolean 처럼 인덱스 서명을 추가해주며 브라켓 표기법을 이용해 프로퍼티에 접근할 수 있게 할 수 있다.
결론
객체의 타입에서 인덱스 서명을 추가해 접근할 수 있게 해주자.
export interface selectedStateInterface {
position: {
[key: string]: boolean,
},
operator: ImgInterface[]
}
'TypeScript' 카테고리의 다른 글
type과 interface 중 뭐가 더 좋을까? (0) | 2024.07.11 |
---|---|
TypeScript 속성 학습 - 3 (0) | 2023.01.27 |
TypeScript 속성 학습 - 2 (1) | 2023.01.26 |
TypeScript 속성 학습 - 1 (1) | 2023.01.24 |