Is it feasible to differentiate generic argument as void in Typescript?

One of the functions in my code has a generic type argument.

In certain cases, when the context is void, I need to input 0 arguments; otherwise, I need to input 1 argument.

If I define the function argument as context: Context | void, I can still add void type even when I should include a context.

Is there a way for me to specify that 0 arguments are expected or check if it is typed as void?

class TestClass<Context = void> {
  protected context : Context

  constructor(context: Context) {
    this.context = context;
  }
}

export function genericVoidNeedArgument<Context = void>(
  context: Context,
) {
  // Can we check the type somehow?
  return new TestClass(context);
}

type UserType = {
  id: string
  // and so on..
};

// Expected output: No, Actual output: Error
// An argument for 'context' was not provided.
genericVoidNeedArgument();

// Expected output: Error, Actual output: Error
genericVoidNeedArgument<UserType>();

// Expected output: Yes, Actual output: Yes
genericVoidNeedArgument<UserType>({id: "123"});

Answer №1

If you want to achieve this, you can make use of Function Overloads.

class NewClass<CustomType = void> {
  protected custom: CustomType;

  constructor(custom: CustomType) {
    this.custom = custom;
  }
}

function genericVoidNeedInput(): NewClass<void>;

function genericVoidNeedInput<CustomType>(
  custom: CustomType
): NewClass<CustomType>;

function genericVoidNeedInput(custom?: any): any {
  return new NewClass(custom);
}

type UserType = {
  id: string;
};

genericVoidNeedInput();
genericVoidNeedInput<UserType>({id: "123"});
genericVoidNeedInput<UserType>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -> Expected 1 argument, but received 0.

Interactive TypeScript Playground

Answer №2

Trying a new method: utilizing constructor overloading with dynamic ...args

type UserType = {
    id: string
    // and so on..
};

class TestClass<Context = void> {
    protected context: Context;

    constructor(...args: Context extends void ? [] : [context: Context])
    constructor(context: Context) {
        this.context = context;
    }
}

const a = new TestClass<UserType>({ id: "123" });
const b = new TestClass<UserType>(); // Expected 1 arguments, but got 0.
const c = new TestClass();

TS Playground

Pro: eliminates the need for an additional function

Con: might be less intuitive to understand

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

Obtain Value from Function Parameter

In my Angular project, I have a function that is called when a button is clicked and it receives a value as an argument. For example: <button (click)="callFoo(bar)">Click Me!</button> The TypeScript code for this function looks like ...

Exploring Angular 2/4: Unpacking the Process of Accessing API Data Using Tokens

Hello there, I am trying to retrieve API data with a token using Angular 2/4. Below is the code I have written: import { Component, ViewEncapsulation } from '@angular/core'; import { Http, Response } from '@angular/http'; import &apos ...

Issue NG8002: Unable to link to 'FormGroup' as it is not recognized as a property of 'form' in Angular 9

I recently created a brand new Angular 9 application with a submodule. Here are my app.modules.ts: import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from & ...

Convert TypeScript-specific statements into standard JavaScript code

For my nextjs frontend, I want to integrate authentication using a keycloak server. I came across this helpful example on how to implement it. The only issue is that the example is in typescript and I need to adapt it for my javascript application. Being u ...

Issue with Angular 6 Share module functionality not functioning as expected

While creating my Angular 6 application, I encountered an issue with sharing a header across multiple pages. I tried including it but it doesn't seem to be working. Can anyone point out what I might be doing wrong? For a demonstration, you can visit . ...

Include a new course based on a specific situation

Is it possible to conditionally add a specific class using vue js? In my DataStore, I have two values defined in TypeScript: value1: 0 as number, value2: 0 as number Based on the values of value1 and value2, I want to apply the following classes in my te ...

Merge two arrays by matching their corresponding identifiers

I have 2 separate arrays that I need to merge. The first array looks like this: const Dogs[] = [ { id: '1', name: 'Buddy' }, { id: '2', name: 'Max' }, ] The second one: const dogAges[] = [ { id: '4&ap ...

In search of assistance with resolving a React Typescript coding issue

I need help converting a non-TypeScript React component to use TypeScript. When attempting this conversion, I encountered the following error: Class 'Component' defines instance member function 'componentWillMount', but ext ...

What is the best way to align a title above menu items within a Material UI app bar when using TypeScript and React?

Check out my current app bar design: app bar image Here is the inspiration for the app bar layout I'm aiming for (title above menu items): inspiration app bar goal This snippet showcases my code: import * as React from 'react'; // More cod ...

What is the recommended return type in Typescript for a component that returns a Material-UI TableContainer?

My component is generating a Material-UI Table wrapped inside a TableContainer const DataReleaseChart = (): React.FC<?> => { return ( <TableContainer sx={{ display: 'grid', rowGap: 7, }} > ...

How to open a PDF file in a new tab using Angular

Within my Angular 12 application, I am seeking to enable users to "view" a PDF file stored locally in the application within a new tab on Google Chrome. Currently, when implementing the code below in HTML, the file downloads rather than opening in a new ta ...

What is the best way to initiate a class constructor with certain parameters left out?

Currently, I am facing a challenge while trying to pass various combinations of arguments to a class constructor. The constructor has 2 optional arguments. Here is the code snippet: class MyClass { foo(a, b) { return new MyClass(a, b); } bar( ...

What is the method for adding a document within an array that is nested within another document?

Apologies if the title seems complex... I struggled to find a better way to describe it. The scenario I am dealing with fits the following Schemes: Collection1: const mongoose = require('mongoose'); const itemSchema = mongoose.Schema({ _id: ...

Troubleshoot: Issue with binding data from DynamicComponentLoader in Angular 2 template

My implementation involves the utilization of DynamicComponentLoader and is based on the Angular2 API Guide. https://angular.io/docs/ts/latest/api/core/DynamicComponentLoader-class.html The code structure I have set up looks like this: import {Page} fro ...

Incorporate a JavaScript library into a personalized JavaScript file that is utilized within my Angular2 project

Integrating Machine Learning into my Angular2 project using the "synaptic.js" JavaScript library is my goal. After executing the command npm install synaptic --save I intend to execute a custom javascript file (myJsFile.js): function myFunction() { v ...

How can you inform TypeScript about a file that will be included using a script tag?

I am currently utilizing TypeScript for my front-end JavaScript development, and I have a situation where I am loading two scripts from my index.html file as shown below: <script src="replacements.js"></script> <script src="socket.js">&l ...

Using Type TTextKey to access TOption is not allowed

I'm struggling to understand why there is a complaint about return option[optionTextKey] with the error message: Type TTextKey cannot be used to index type TOption Here's the code snippet causing the issue: type Props< TTextKey, TOpti ...

Explaining the structure of a nested object within a TypeScript declaration file

As I work on my project, I encounter the challenge of importing an object created by a dynamic function. The dynamic nature of the keys on this object poses a problem for the IDE, as it cannot determine what keys are present based on the provided config. T ...

What is the best way to connect input values with ngFor and ngModel?

I am facing an issue with binding input values to a component in Angular. I have used ngFor on multiple inputs, but the input fields are not showing up, so I am unable to push the data to subQuestionsAnswertext. Here is the code snippet from app.component ...

Tips for preventing CORS and SSL issues when using localhost

Attempting to log in with Google on my Svelte app involves sending a request to an Express server. However, I encounter different errors on different browsers. On Firefox, I receive a Cross-Origin Request Blocked: The Same Origin Policy disallows reading t ...