Home > OS >  Is it possible to make a function parameter optional by condition?
Is it possible to make a function parameter optional by condition?

Time:09-27

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

then the compiler does not swear. But if I do it conditionally I get an error "Expected 2 arguments, but got 1."

CodePudding user response:

I would suggest to replace the argument with a variadic tuple type. If A is never, we evaluate TestType to be an empty tuple. If not, TestType resolves to a tuple with a single element containing A.

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

/* ... */

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

Here are some tests:

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

  • Related