Причина отсутствия ошибки в том, что ваш параметр tConstructor
принимает любое количество параметров любого типа.
Если вы хотите быть более строгими в отношении того, какие параметры разрешены, вы можете использовать типы кортежей, чтобы точно указать, какие параметры принимает tConstructor
, например:
class Creator<T>
{
constructor(tConstructor: new (...args: [string]) => T) {
// ^^^^^^^^
// note that args is a tuple containing exactly one item, namely a string
const it: T = new tConstructor();
// ^^^^^^^^^^^^^^^^^^
// This is now wrong because the constructor takes a string as parameter
}
}
const e1 = new Creator<OneArgConstructorClass>(OneArgConstructorClass);
const e2 = new Creator<OneArgConstructorClass>(TwoArgConstructorClass);
// ^^^^^^^^^^^^^^^^^^^^^^^
// This is now also wrong because the constructor signatures are not compatible
Если вы сделали ...args
Если подпись [string, number]
, то ваш вызов new tConstructor()
все равно будет неправильным, потому что вы не задали ему 2 обязательных параметра, но new Creator<OneArgConstructorClass>(TwoArgConstructorClass)
будет в порядке, поскольку теперь он получает правильные 2 параметра.
В отличие от того, что вы можете ожидать, new Creator<OneArgConstructorClass>(OneArgConstructorClass)
также больше не выдает ошибку, потому что конструктор, который принимает 1 параметр, будет безопасно игнорировать любые дополнительные параметры, которые он получает.
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ
Если вы хотите типизированный способ вызова конструкторов классов, вам нужно сделать что-то вроде этого:
// Note the constraint that T must be "new"able
class Creator<T extends new (...args: any[]) => any>
{
// ConstructorParameters is a builtin TS utility that when given a class returns the type of its parameters in a tuple
// Note that we need to pass the actual parameters in somehow; in this example I've made Creator#constructor take 2 parameters:
// 1) the class
// 2) its constructor parameters in a tuple
constructor(tConstructor: new (...args: ConstructorParameters<T>) => any,
argsArray: ConstructorParameters<T>) {
// Construct the class with the arguments array!
const it: T = new tConstructor(...argsArray);
}
}
// This will now work
const e1 = new Creator<typeof OneArgConstructorClass>(OneArgConstructorClass, ['hello']);
// This will now *not* work, which is correct, as the constructor signatures don't match
const e2 = new Creator<typeof OneArgConstructorClass>(TwoArgConstructorClass, ['hello', 14]);
// ^^^^^^^^^^^^^^^^^^^^^^
// Argument of type 'typeof TwoArgConstructorClass' is not assignable to parameter of type 'new (name: string) => any'.
// This *will* work because the signatures match
const e3 = new Creator<typeof TwoArgConstructorClass>(TwoArgConstructorClass, ['hello', 14]);