First, consider the following notation from your original question:

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

Using this notation, you typecast the returned object to the type AddTodoAction. However, the function's declared return type is still undefined (and the compiler will implicitly assume any as return type).

Use the following notation instead:

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

In this case, omitting a required property will yield the expected compiler error. For example, omitting the text property will generate the following (desired) error:

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"'.

Also see the playground example.

Answer from helmbert on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › typescript › explain-the-arrow-function-syntax-in-typescript
Explain the arrow function syntax in TypeScript - GeeksforGeeks
September 11, 2025 - Arrow functions in TypeScript are similar to JavaScript (ES6) but allow you to add type annotations for parameters and return values.
🌐
TutorialsPoint
tutorialspoint.com › typescript › typescript_arrow_functions.htm
TypeScript - Arrow Functions
Arrow functions are a concise way to write the anonymous functions in TypeScript. They are introduced in ES6 (ECMAScript 2015). They offer a shorter and more readable syntax compared to traditional function declarations.
🌐
Tutorial Teacher
tutorialsteacher.com › typescript › arrow-function
TypeScript Arrow Functions
In the above example, sum is an arrow function. (x:number, y:number) denotes the parameter types, :number specifies the return type. The fat arrow => separates the function parameters and the function body.
🌐
CodeSignal
codesignal.com › learn › courses › learning-functions-using-typescript › lessons › understanding-arrow-functions
Understanding Arrow Functions | CodeSignal Learn
Here, we define a function with ... come after the required parameters. ... Arrow functions in TypeScript introduce a concise syntax for writing functions, focusing on simplifying function expressions....
Top answer
1 of 5
281

First, consider the following notation from your original question:

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

Using this notation, you typecast the returned object to the type AddTodoAction. However, the function's declared return type is still undefined (and the compiler will implicitly assume any as return type).

Use the following notation instead:

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

In this case, omitting a required property will yield the expected compiler error. For example, omitting the text property will generate the following (desired) error:

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"'.

Also see the playground example.

2 of 5
10

There are 2 ways of achieving this with proper typing and minimal code:

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

Now the TS compiler can check the returned types. For example:

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'.
🌐
Convex
convex.dev › core concepts › functions & methods › arrow
Arrow | TypeScript Guide by Convex
Arrow functions solve both problems. They give you a cleaner syntax and automatically bind this to the surrounding context, which prevents those frustrating runtime errors. In this guide, we'll cover practical patterns for using TypeScript arrow functions: syntax shortcuts, type annotations, async operations, when to choose them over regular functions, and how to avoid common mistakes.
🌐
GitBook
basarat.gitbook.io › typescript › future-javascript › arrow-functions
Arrow Functions | TypeScript Deep Dive
February 12, 2020 - Lovingly called the fat arrow (because -> is a thin arrow and => is a fat arrow) and also called a lambda function (because of other languages). Another commonly used feature is the fat arrow function ()=>something. The motivation for a fat arrow is: ... For a language that claims to be functional, in JavaScript you tend to be typing function quite a lot.
🌐
GeeksforGeeks
geeksforgeeks.org › typescript › what-are-arrow-lambda-functions-in-typescript
What are Arrow/lambda functions in TypeScript ? - GeeksforGeeks
January 23, 2025 - Arrow functions in TypeScript (also known as lambda functions) are concise and lightweight function expressions using the => syntax.
Find elsewhere
🌐
Scaler
scaler.com › home › topics › typescript › working with arrow functions
TypeScript Arrow function - Scaler Topics
May 4, 2023 - Arrow functions, a new way to write anonymous function expressions are similar to lambda in other programming languages. It is also called the fat arrow. The arrow function has a lexical scoping of the this keyword.
🌐
Javatpoint
javatpoint.com › typescript-arrow-function
TypeScript Arrow function - javatpoint
TypeScript Arrow function with typescript tutorial, typescript introduction, versions, typescript and javascript, features, components, installation, typescript first program, typescript types, etc.
🌐
typescriptlang.org
typescriptlang.org › docs › handbook › 2 › functions.html
TypeScript: Documentation - More on Functions
The JavaScript specification states ... and so TypeScript uses that syntax space to let you declare the type for this in the function body. ... This pattern is common with callback-style APIs, where another object typically controls when your function is called. Note that you need to use function and not arrow functions ...
🌐
Medium
medium.com › @aymenfarhani28 › understanding-arrow-functions-default-parameters-and-spread-operator-in-typescript-0e5872b7ec24
Understanding Arrow Functions, Default Parameters and Spread Operator in TypeScript | by Aymen FARHANI | Medium
February 25, 2025 - Lexical scoping of this: In traditional functions, this is dynamically bound, whereas in arrow functions, this is lexically bound, meaning it retains the value of this from the surrounding context. ... In TypeScript (and JavaScript), you can set default values for function parameters.
🌐
Gitbook
jorgedacostaza.gitbook.io › typescript-pt › future-javascript › arrow-functions
Arrow Functions | Typescript - GitBook
If you run this code in the browser this within the function is going to point to window because window is going to be what executes the growOld function. Fix is to use an arrow function: The reason why this works is the reference to this is captured by the arrow function from outside the function body. This is equivalent to the following JavaScript code (which is what you would write yourself if you didn't have TypeScript...
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Functions › Arrow_functions
Arrow function expressions - JavaScript - MDN Web Docs
February 21, 2026 - An arrow function expression is a compact alternative to a traditional function expression, with some semantic differences and deliberate limitations in usage:
🌐
Programiz
programiz.com › typescript › arrow-function
TypeScript Arrow Function
The arrow function square() takes one argument x and returns its square. Hence, calling square() with the value 5 returns 25. Inside a regular function, this keyword usually refers to the function where it is called.
🌐
DevCamp
devcamp.com › trails › introduction-typescript › campsites › basic-syntax › guides › typescript-arrow-functions
TypeScript Arrow Functions
Now what I'm going to talk about is a shorthand version for creating functions which is called the arrow function. So there are a number of benefits to it. One very nice one is that you don't have to type in the function key word anymore. Another nice benefit is how it works with the “this” ...
🌐
CodeCraft
codecraft.tv › courses › angular › es6-typescript › arrow
Fat Arrow Functions • Angular - CodeCraft
In the first example we write return a + b but in the fat arrow version we just wrote a + b. That’s because in the fat arrow syntax if it is on one line, the statement gets returned automatically without the need to use the return keyword. Let’s imagine we have an object with a function called sayLater, like so:
🌐
Typescriptworld
typescriptworld.com › home › mastering arrow functions in typescript: a comprehensive guide for modern developers
Mastering Arrow Functions in TypeScript: A Comprehensive Guide for Modern Developers – React News | Modern UI Development
Instead, they inherit these values from the enclosing lexical scope. This single feature eliminates a whole class of common bugs related to context loss in callbacks and event handlers. This article provides a comprehensive deep dive into Arrow Functions in TypeScript.