Typescript requires that the argument passed is undefined

Typescript: 2.4.1

I am exploring the creation of a helper function to produce redux action creators.

Here is what I have:

interface IAction<T extends string, P = undefined> {
    type: T;
    payload: P;
}

function createAction<T extends string>(type: T): () => IAction<T, undefined>;
function createAction<T extends string = '', U = undefined, V = {}>(type: T, actionCreator: (payload: U) => V): (payload: U) => IAction<T, V>;
function createAction<T extends string>(type: T, actionCreator?: (payload?: any) => any) {
    return (payload: any) => ({
        payload,
        type,
    });
}

enum ActionType {
    INCREMENT = 'COUNTER/INCREMENT',
    DECREMENT = 'COUNTER/DECREMENT',
    ASYNC_INCREMENT = 'COUNTER/ASYNC_INCREMENT',
}

const increment = createAction(ActionType.INCREMENT, () => ({ amount: 1 }));
const incrementBy = createAction(ActionType.INCREMENT, (amount: number) => amount);

In this instance, I anticipate increment being a function that requires no arguments, and incrementBy needing exactly one input (a number).

incrementBy functions correctly, however, when calling increment() without any arguments, Typescript generates the following error:

[ts] Expected 1 argument, but received 0;

When attempting to call it in the same way as incrementBy, for example with increment(42), I encounter this error:

[ts] Argument of type '42' is not compatible with parameter of type 'undefined';

For it to work, I need to do this: increment(undefined).

Is there a solution to address this issue?

Answer №1

To improve your code, consider adding another overload that specifies the return of a function with no arguments instead of a function that only takes undefined as an argument.

function createCustomAction<T extends string>(type: T): () => ICustomAction<T, undefined>;
function createCustomAction<T extends string, V>(type: T, customActionCreator: () => V): () => ICustomAction<T, V>;
function createCustomAction<T extends string, U, V>(type: T, customActionCreator: (payload: U) => V): (payload: U) => ICustomAction<T, V>;
function createCustomAction<T extends string, U, V>(type: T, customActionCreator?: (payload: U) => V): (payload: U) => ICustomAction<T, V> {
    return (payload: any) => ({
        payload,
        type,
    });
}

It appears that your existing implementation does not utilize the passed function. Consider updating it like this:

function createCustomAction<T extends string>(type: T): () => ICustomAction<T, undefined>;
function createCustomAction<T extends string, V>(type: T, customActionCreator: () => V): () => ICustomAction<T, V>;
function createCustomAction<T extends string, U, V>(type: T, customActionCreator: (payload: U) => V): (payload: U) => ICustomAction<T, V>;
function createCustomAction<T extends string, U, V>(type: T, customActionCreator?: (payload: U) => V): (payload: U) => ICustomAction<T, V> {
    if (customActionCreator) {
        return (payload: U) => ({
            payload: customActionCreator(payload),
            type,
        });
    } else {
        return () => ({
            payload: undefined,
            type
        });
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing field visibility in Angular Reactive form (form validation) by toggling based on a checkbox in another component

I'm facing a challenge with a complex form where the fields depend on toggling checkboxes in a separate component (parent). My goal is to dynamically validate the form, with some fields being enabled and others disabled based on the toggling of the ch ...

Using Systemjs to transpile TypeScript async functions

When I manually build .ts files using the tsc tool, I notice that wrappers are generated for async/await keywords. However, I am facing an issue setting up transpile on-the-fly using SystemJS. Here is my index.htm configuration: <script src="https:// ...

Transferring information from a service to a parent component, and subsequently passing it to a child component

Hello everyone, I am a beginner with Angular and I seem to have run into an issue that I can't figure out. In my parent component, I am attempting to pass the weekly variable to my child component but it doesn't seem to be working as expected. H ...

Can you explain the meaning behind this TypeScript variable declaration syntax?

Can anyone explain the meaning of this code snippet: myCollection: Collection|any = null; I'm having trouble understanding it... Does it indicate that myCollection is set to type Collection, (which is an interface), with a default value of null? But ...

Guide to creating a one-to-one object literal map with a different value type using a function return without explicitly defining the return type

At the moment, I have successfully managed to combine the keys and values of each object literal that is passed into a function. For example: interface StaticClass<T = any> { new (...args: any[]): T } type RecordOfStaticClasses = Record<string, ...

Having trouble accessing a downloaded image saved in local files from Amazon S3 using the AWS SDK in Node.js

I am currently using the node.js aws-sdk package to download files from s3 storage. However, when I download a jpeg image and save it as a local file, I am unable to view it. Is this the correct method for downloading jpeg images? public async downloadFi ...

Utilizing TypeScript to spread properties onto a component and destructure them from within components

I'm trying to optimize my use of props spreading and destructuring when working with components. Currently, I spread my props in this manner: <RepositoryItem {...node} /> Then, within the component, I destructure the props like so: interface ...

Can metadata be attached to data models in Angular for annotation purposes?

Looking to add some metadata annotations to a simple data model export class Certification { title: string; certificationType?: CertificationType; validTo?: number; description?: string; externalIdentifier: Guid; constructor() { ...

Typescript: Maximizing efficiency and accuracy

When it comes to developing Angular2 apps using Typescript, what are the essential best practices that we should adhere to? ...

The use of throwError(error) has been phased out, however, no replacement has been introduced for the Error(HttpErrorResponse)

It seems like the use of throwError(error) is deprecated now. VS Code suggests using throwError(() => new Error('error')) instead, as new Error(...) only accepts strings. How can I replace it correctly without causing issues with my HttpErrorH ...

Step-by-step guide to creating a custom wrapper in React that modifies the props for a component

Exploring React components for the first time and seeking assistance. I am interested in dynamically wrapping one component inside another and modifying its props. For instance, considering the following component: If we want to pass the key3 from a wrapp ...

``Changing the value of a class variable in Angular 2 does not result in the

I am facing an issue with a component that contains a variable called myName export class ConversationComponent implements OnInit { private myName: string; showNames(name) { this.myName=name; } } The value is assigned using the showNames() m ...

The powerful combination of Visual Studio 2015, TypeScript, Cordova, Angular 2, and System

I am encountering an issue with the loading of external modules using systemJS. I have created a small sample project for VS2015. Feel free to check out the code here: https://github.com/dbiele/TypeScript-Cordova-SystemJS After building the project and at ...

When trying to access a private component by typing its URL into the browser's address bar, the page fails to load (React-router v4)

As I work on developing an app that requires authentication, I am utilizing react-router and react-router-redux to handle routing. Everything runs smoothly when navigating from non-private routes, but I encounter an issue when entering a private route&apos ...

How can I generate pure JavaScript, without using Typescript modules?

Take this scenario as an example ... index.ts import { x } from "./other-funcs"; function y() { alert("test"); } x(y); other-funcs.ts import { z } from "some-module"; export function x(callback: () => void): void { z(); callback(); } ...

Issue with for loop execution within subscribe event

In my chat design, there is a list of people on the left side. When a user clicks on any person, I display their chat history on the right side. To achieve this, I need to transfer user details from one component to another using an RXJS subscribe call. Da ...

Make sure the static variable is set up prior to injecting the provider

In our Angular6 application, we utilize a globalcontextServiceFactory to initialize the application before rendering views. This process involves subscribing to get configuration from a back-end endpoint and then using forkJoin to retrieve environment app ...

When using TypeORM's save() method with an array of objects, the @PrimaryColumn() annotations are ignored, resulting

My current situation involves an entity called Point: @Entity() export class Point { @PrimaryGeneratedColumn('uuid') id: string; @IsUUID() @PrimaryColumn({ type: 'uuid', ...

What is the process for creating a node module with TypeScript?

So, with regards to the previous question about importing a module using typescript, here is a general answer: 1) Start by creating a blah.d.ts definition file. 2) Use the following code snippet: /// <reference path="./defs/foo/foo.d.ts"/> import ...

What exactly does the statement if(item.some((item) => !item.available) represent in typescript?

Can you explain the meaning of if(item.some((item) => !item.available))? While looking at some code randomly, I came across this snippet: if(item.some((item) => !item.available){ } I'm curious about what it signifies. Can you elaborate on it? ...