[typescript] TypeScript 화살표 함수에서 반환 유형 지정

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}; };


답변