当前位置: 首页 > 知识库问答 >
问题:

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

司寇经亘
2023-03-14

我使用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”的方式(我想这可能不是问题)

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

共有3个答案

鲁滨海
2023-03-14

有两种方法可以通过正确的键入和最少的代码来实现这一点:

interface AddTodoAction {
    type: "ADD_TODO",
    text: string
};

// Because the this keyword works different in arrow functions these 
// 2 implementations are different in some cases:

// arrow function form/ function expression
const addTodo1 = (text: string): AddTodoAction => ({
    type: "ADD_TODO",
    text: text
})

// function declaration form
function addTodo2 (text: string): AddTodoAction {
    return ({
        type: "ADD_TODO",
        text: text
    })
}

现在TS编译器可以检查返回的类型。例如:

const todo = addTodo1('hi');

// Following gives TS compile time error
// addTodo1 returns AddTodoAction which does not have id on the type

const id = todo.id // Property 'id' does not exist on type 'AddTodoAction'.
杜俭
2023-03-14

我认为最好是为函数创建一个具有正确类型的接口,然后只需指定该类型,而不是接口的所有嵌套类型:

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}; 
};
高墨一
2023-03-14

首先,从你原来的问题中考虑下面的符号:

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

使用此表示法,可以将返回的对象类型转换为类型addtoAction。但是,函数声明的返回类型仍然未定义(编译器将隐式地假定any为返回类型)。

请改用以下符号:

export const addTodo3 = (text: string): AddTodoAction => ({
    type: "ADD_TODO",
    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"'.

另请参见操场示例

 类似资料:
  • 它必须是基本的,但请帮助我理解为什么这不起作用。 当我编写一个普通的arrow函数并返回jsx时,它就工作了。但是,当我使用async/await请求和相同的arrow函数返回jsx时,它失败了。 编辑: 实际上,我必须在列表视图中显示用户的配置文件图像。所以,我调用这个函数来检索我的块中相应用户的图像 这很有效 但事实并非如此

  • 问题内容: 从箭头函数返回对象时,由于语法上的歧义,似乎有必要使用额外的和关键字集。 那意味着我不会写,但必须写。 如果arrow函数返回的不是对象,则和都是不必要的,例如:。 返回。 修饰符抛出 “::意外标记:‘”。 有什么明显的我想念的吗? 问题答案: 您必须将返回的对象文字包装在括号中。否则,花括号将被视为表示功能的主体。以下作品: 您不需要将任何其他表达式包装到括号中: 等等。

  • 本文向大家介绍箭头函数中this指向举例?相关面试题,主要包含被问及箭头函数中this指向举例?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: //输出22 定义时绑定。

  • 不鼓励将箭头函数(“lambdas”)传递给 Mocha。Lambdas词法绑定 this,无法访问 Mocha 上下文。例如,以下代码将失败: describe('my suite', () => { it('my test', () => { // should set the timeout of this test to 1000 ms; instead will fail thi