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