小编典典

在 TypeScript 箭头函数中指定返回类型

all

我正在使用 React 和 Redux 并将操作类型指定为接口,以便我的 reducer 可以利用标记的联合类型来提高类型安全性。

因此,我的类型声明如下所示:

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在函数中处理 ‘ ‘
的方式(这可能不是问题,我想。)

有什么关于最好的方法的建议吗?


阅读 101

收藏
2022-07-30

共1个答案

小编典典

首先,考虑原始问题中的以下符号:

export const addTodo3 = (text: string) => <AddTodoAction>({
    type: "ADD_TODO",
    text
})

使用此表示法,您将返回的对象类型转换为 type 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"'.

另请参阅操场示例

2022-07-30