Emit 이벤트를 통해 전달한 value의 값이 항상 any이기 때문에 발생하는 타입 오류를 해결하기 위해 고민한 흔적~^^
아래에서는 단계적으로 정리해뒀다.
1. 타입 정의 X
const emit = defineEmits(['update:value']);
const setSelectedValue = (value) => {
emit('update:value', value);
};
이때 value의 타입은 따로 명시해주지 않았기 때문에 any이다.
근데 이 경우 공통 컴포넌트를 앱에 전역 등록해주면, vue 파일에서 emit 이벤트를 받아서 변수를 업데이트해 줄 때,
@update:value="(value) => props.row.data.volType = value"
이런 TypeError가 나타난다.
Parameter 'value' implicitly has an 'any' type.
2. 인터페이스 사용
인터페이스를 정의하여 value에 적절한 타입을 명시해줬다.
interface Cascade {
dtlCd: string
dtlNm: string
isCascade: boolean
}
interface emitType {
'update:value': (value: Cascade) => void;
}
const emit = defineEmits<emitType>();
Record<string, any[]> 제한을 맞춰야 한다며 별 트집을 다 잡는다.
Type 'emitType' does not satisfy the constraint 'Record<string, any[]> | ((...args: any[]) => any)'.
Type 'emitType' is not assignable to type 'Record<string, any[]>'.
Index signature for type 'string' is missing in type 'emitType'.
https://github.com/microsoft/TypeScript/issues/42825
Types declared as an "interface" do not extend Record<PropertyKey, unknown>
인터페이스 사용 시 발생하는 버그인 것 같다. 최신 버전에서는 고친 것 같은데 난 아직 3.3 버전을 쓰고 있으니 사용할 수 없을 것 같다.
3. Type 사용
type emitType = {
'update:value': [value: cascadeT];
};
const emit = defineEmits<emitType>();
const selectedValue = computed(() => props.value);
const setSelectedValue = (value: cascadeT) => {
emit('update:value', value);
};
뭐 타입은 다 잘 적용이 됐다.
다만 내가 해결하고 싶던 상위 컴포넌트에서 emit 이벤트를 통해 전달받는 value의 타입이 any로 되는 것은 막지 못했다.
대체 왜….????!!!! 지긋지긋한 any…
[ 참고 자료 ]
'Typescript' 카테고리의 다른 글
인덱스 시그니처 (0) | 2024.05.14 |
---|---|
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type (0) | 2024.03.27 |
Typescript 인터페이스 네이밍 규칙 어떻게 할까? | 접두사 I를 사용하면 안 되는 이유 (1) | 2024.03.27 |
@input event의 타입 (0) | 2024.03.27 |
타입스크립트 인터페이스 어떻게 선언할까? declare / export (0) | 2024.03.27 |