Как уже упоминалось в комментариях, T extends NoParameterCtor<T>
- это необычное ограничение, которое означает, что "T
- это конструктор, который создает новые экземпляры сам по себе".Если вы не пытаетесь описать самовоспроизводящиеся конструкторы, это не то, что вы имеете в виду.
Если вы просто хотите, чтобы T
было «чем-то новым», вам не нужно заботиться о типе экземпляра.Предполагая, что вы используете TS3.0 или новее, вы можете использовать unknown
для обозначения любого типа, хотя вы также можете использовать any
.Поэтому, возможно, вы хотите, чтобы Bar
было
interface Bar<T extends NoParameterCtor<unknown>> { }
Следующее по-прежнему не будет работать, хотя:
class Zar implements Bar<Zoo> { } // error!
// Zoo does not satisfy the constraint NoParameterCtor<unknown>
Это потому, что тип Zoo
не является новым;это тип экземпляра класса Zoo
.Я не знаю, если вас смущает разница между именованными значениями и именованными типами в TypeScript, но вы в хорошей компании, если это так.Вкратце, class Zoo {}
вводит тип с именем Zoo
, который является типом экземпляров класса, и значение с именем Zoo
, который является конструктором такогоэкземпляров.И тип значения Zoo
не является типом Zoo
.Чтобы сослаться на тип значения конструктора Zoo
, вместо него необходимо использовать typeof Foo
:
class Zar implements Bar<typeof Zoo> { } // okay
Также я предполагаю, что вы удалили содержимое Bar
, Zar
иZoo
потому что они здесь не актуальны.Но, чтобы быть ясным, пустые интерфейсы соответствуют практически всем, потому что TypeScript использует структурную типизацию .Если Bar
требуется доступ к типу экземпляра T
, то вы можете использовать псевдоним встроенной библиотеки InstanceType<>
, чтобы получить его:
interface Bar<T extends NoParameterCtor<unknown>> {
theConstructor: T,
theInstance: InstanceType<T>
}
class Zar implements Bar<typeof Zoo> {
theConstructor = Zoo; // the constructor
theInstance = new Zoo(); // an instance
}
Надеюсь, чтопомогает.Удачи!