React와 Redux를 사용하고 있으며 인터페이스로 지정된 작업 유형이 있으므로 감속기가 유형 안전성을 향상시키기 위해 태그 지정된 공용체 유형을 활용할 수 있습니다.
따라서 다음과 같은 유형 선언이 있습니다.
interface AddTodoAction {
type: "ADD_TODO",
text: string
};
interface DeleteTodoAction {
type: "DELETE_TODO",
id: number
}
type TodoAction = AddTodoAction | DeleteTodoAction
이러한 액션을 만드는 도우미 함수를 만들고 싶은데 화살표 함수를 사용하는 편입니다. 내가 이것을 쓰면 :
export const addTodo1 = (text: string) => ({
type: "ADD_TODO",
text
});
컴파일러는 AddTodoAction
반환 유형이 명시 적으로 지정되지 않았기 때문에 이것이 유효한지 확인하는 데 도움을 줄 수 없습니다 . 다음과 같이 명시 적으로 반환 유형을 지정할 수 있습니다.
export const addTodo2: (text: string) => AddTodoAction = (text: string) => ({
type: "ADD_TODO",
text
})
그러나 이것은 내 함수 인수를 두 번 지정해야하므로 장황하고 읽기가 더 어렵습니다.
화살표 표기법을 사용할 때 반환 유형을 명시 적으로 지정할 수있는 방법이 있습니까?
나는 이것을 시도해 보았다.
export const addTodo3 = (text: string) => <AddTodoAction>({
type: "ADD_TODO",
text
})
이 경우 컴파일러는 이제 반환 유형을 다음과 같이 유추 AddTodoAction
하지만 반환 하는 개체에 적절한 필드가 모두 있는지 확인하지 않습니다.
다른 함수 구문으로 전환하여이 문제를 해결할 수 있습니다.
export const addTodo4 = function(text: string): AddTodoAction {
return {
type: "ADD_TODO",
text
}
}
export function addTodo5(text: string): AddTodoAction {
return {
type: "ADD_TODO",
text
}
}
이 방법 중 하나를 사용하면 컴파일러가 올바른 반환 유형을 사용하고 모든 필드를 적절하게 설정하도록 강제 할 수 있지만, 또한 더 장황하고 this
함수에서 ‘ ‘가 처리 되는 방식을 변경합니다 (문제가되지 않을 수 있음). 나는 추측한다.)
이를 수행하는 가장 좋은 방법에 대한 조언이 있습니까?
답변
먼저 원래 질문에서 다음 표기법을 고려하십시오.
export const addTodo3 = (text: string) => <AddTodoAction>({
type: "ADD_TODO",
text
})
이 표기법을 사용하여 반환 된 객체를 유형으로 형변환합니다 AddTodoAction
. 그러나 함수의 선언 된 반환 유형은 여전히 정의되어 있지 않으며 컴파일러는 암시 적 any
으로 반환 유형으로 가정 합니다.
대신 다음 표기법을 사용하십시오.
export const addTodo3 = (text: string): AddTodoAction => ({
type: "ADD_TODO",
text: text
})
이 경우 필수 속성을 생략하면 예상되는 컴파일러 오류가 발생합니다. 예를 들어 text
속성을 생략하면 다음과 같은 (원하는) 오류가 생성됩니다.
Type '{ type: "ADD_TODO"; }' is not assignable to type 'TodoAction'.
Type '{ type: "ADD_TODO"; }' is not assignable to type 'DeleteTodoAction'.
Types of property 'type' are incompatible.
Type '"ADD_TODO"' is not assignable to type '"DELETE_TODO"'.
또한 플레이 그라운드 예제를 참조하십시오 .
답변
가장 좋은 방법은 올바른 유형을 가진 함수에 대한 인터페이스를 만드는 것입니다. 그러면 인터페이스의 모든 중첩 유형이 아닌 해당 유형 만 지정하면됩니다.
interface AddTodoAction {
type: "ADD_TODO",
text: string
};
interface AddTodoActionCreator {
(text: string): AddTodoAction;
};
export const addTodo: AddTodoActionCreator = (text) => ({
type: "ADD_TODO",
text
});
업데이트 : 유형으로이 작업을 수행하는 방법
export interface GeneralAction<T> {
type: string;
payload: T;
}
export interface GeneralActionCreator<T> {
(payload: T): GeneralAction<T>;
}
export const SAVE_EVENT = 'SAVE_EVENT';
export const SaveEvent: GeneralActionCreator<UserEvent> = (payload) => { return {type: SAVE_EVENT, payload}; };