Is it feasible to conditionally set a function parameter as optional?

type TestType<A> = [A] extends [never] ? void : A

class Singleton<T, A> {
    private ClassRef: (new (...args: A[]) => T)
    private args: TestType<A>
    private _instance?: T

    constructor(ClassRef: (new (...args: A[]) => T), args: TestType<A>) {
        this.ClassRef = ClassRef
        this.args = args
    }

    public get instance() {
        if (!this._instance) {
            this._instance = new this.ClassRef(this.args as A)
        }

        return this._instance
    }
}

class Empty {}

const test = new Singleton(Empty)

If I specify

type TestType<A> = void

The compiler does not show any errors. However, when I do it conditionally, I encounter an error saying "Expected 2 arguments, but got 1."

Answer №1

To enhance the program, I recommend substituting the argument with a variadic tuple type. When A is of type never, the outcome for TestType will be an empty tuple. On the other hand, if not, TestType will result in a tuple containing a single element that holds A.

type TestType<A> = [A] extends [never] ? [] : [args: A]

/* ... */

constructor(ClassRef: (new (...args: A[]) => T), ...args: TestType<A>) {
    this.ClassRef = ClassRef
    this.args = args
}

Below are some test scenarios:

class Empty {}
class NotEmpty {
  constructor(arg: string) {}
}

const test1 = new Singleton(Empty)
const test2 = new Singleton(NotEmpty) 
//                          ^^^^^^^^ Error: Arguments for the rest 
//                                   parameter 'args' were not provided
const test3 = new Singleton(NotEmpty, "abc")

Playground

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

Tips for implementing a generic constant value in a TypeScript function

Is it permissible in TypeScript to have the following code snippet? function getFoo<P = "a"|"b">():string { // P represents a type, not an actual value! return "foo"; } getFoo<"a>">(); // no ...

What is the best way to transform a Storybook typescript meta declaration into MDX format?

My typescript story file is working fine for a component, but new business requirements call for additional README style documentation. To meet this need, I am trying to convert the .ts story into an .mdx story. However, I am facing challenges in adding de ...

Implementing theme in Monaco editor without initializing an instance

I recently developed a web application incorporating Monaco Editor. To enhance user experience, I also integrated Monaco for syntax highlighting in static code blocks. Following guidance from this source, I successfully implemented syntax highlighting wit ...

Pagination feature in MUI DataGrid table is malfunctioning

I'm struggling to get the pagination feature to work in my Material UI DataGrid component, but I'm hitting a roadblock: https://i.stack.imgur.com/eT7s7.gif The console is not showing any errors. Here is the code for my component: import { ...

Creating an array of Form Groups involves first initializing an empty array and then

Here is a JSON object that I need to create a reactive form based on. What steps should I take for the array portion specifically? { "examName" : "java", "password" : "1234.com", "examCategory" : { "id" : 78 }, "examDetailSet" ...

Creating an object efficiently by defining a pattern

As a newcomer to Typescript (and Javascript), I've been experimenting with classes. My goal is to create an object that can be filled with similar entries while maintaining type safety in a concise manner. Here is the code snippet I came up with: le ...

Before running any unit tests, I have to address all linting issues as required by ng test

Upon running ng test, the output I receive is as follows: > ng test 24 12 2019 14:20:07.854:WARN [karma]: No captured browser, open http://localhost:9876/ 24 12 2019 14:20:07.860:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/ ...

Having trouble receiving a blob response using HttpClient POST request in Angular 9?

I'm encountering an issue while attempting to receive a zip file as a blob from an HTTP POST request. However, the resolved post method overload is not what I expected. const options = { responseType: 'blob' as const }; Observable<Blob ...

ReactJS and Redux: setting input value using properties

I am utilizing a controlled text field to monitor value changes and enforce case sensitivity for the input. In order to achieve this, I need to access the value property of the component's state. The challenge arises when I try to update this field ...

Is it possible to use TypeScript or Angular to disable or remove arrow key navigation from a PrimeNG Table programmatically?

Is there a way to programmatically prevent left and right arrow key navigation in a PrimeNG Table with cell editing, without the need to modify the Table component source code? You can check out an example here: Angular Primeng Tableedit Demo code. I mana ...

Exploring Sequelize: Uncovering the Secret to Retrieving Multiple Associated Items of Identical Type

Within my database, I have a situation where there are two tables sharing relations of the same type. These tables are named UserCollection and ImagenProcess UserCollection has two instances that relate to ImagenProcess. Although the IDs appear unique whe ...

The parameter 'EventTypes' cannot be assigned to a type of string

I am working on enhancing the functionality of the function provided below by adding types to it, clickEvent(event:Event) { this.event = event } The HTML Code: <a [href]="href" [target]="target" (click)="clickEvent('text')"></ ...

I'm curious about how to implement textarea functionality within Angular for modeling purposes

I have a desire to utilize the model and transmit it to the server. One instance of this is sending comments. comment.model.ts export interface Comment { article_no: number; username: string; nickname: string; creatat: Date; content: string; } ...

Struggling to assign the correct data type to a property in Typescript

I am encountering a TypeScript error with the following code. In this interface, the 'items' property can be either an object or an array depending on the code and response. I am unsure how to specify the datatype of 'array/object/any', ...

Tips for determining the minimum value within an array of objects across multiple keys using a single function

I am currently tasked with the challenge of determining the minimum value from an array of objects that contain multiple keys. My ultimate goal is to identify the minimum value among all keys or specific keys within the objects. For instance var users = ...

"NameService is not provided in Angular, please check your module

I've been struggling with loading a class into my Angular component. I've spent quite some time trying to figure out the solution, even attempting to consolidate everything into a single file. Here is what I have: Application.ts /// <referenc ...

Tips for eliminating Ref upon exiting the screen on React / React Native?

When navigating back in React / React Native, I am encountering keyboard flickering caused by the presence of Ref on the screen. I would like to remove it before leaving the screen. The code snippet I am using is as follows: // To focus on the input fie ...

Utilizing string to access property

Is there a better way to access interface/class properties using strings? Consider the following interface: interface Type { nestedProperty: { a: number b: number } } I want to set nested properties using array iteration: let myType: Type = ...

Troubleshooting Problem with Uploading Several Photos to Firebase Storage

I need assistance with uploading multiple photos to Firebase Storage. Despite my efforts, it seems that the original upload keeps getting overwritten and the folder with the venueID property is not being created. Can someone provide some guidance on this i ...

The file that is currently being downloaded has the .pptx extension, but it is being

Take a look at this code snippet: const generateDownload = ({ link, data, title, settings })=> { const newLink = document.createElement('a'); const blobUrl = link || URL.createObjectURL(new Blob([data], settings)); newLink.setAt ...