Я в основном пытаюсь сделать что-то вроде этого:
interface gen1<T> {
constructor(param: T);
}
interface gen2<T> {
constructor(param: gen1<any>);
}
class genImpl implements gen2<any> {
constructor(param: gen1<any>) {
}
}
Но получаю ошибку:
Class 'genImpl' incorrectly implements interface 'gen2<any>'.
Types of property 'constructor' are incompatible.
Type 'Function' is not assignable to type '(param: gen1<any>) => any'.
Type 'Function' provides no match for the signature '(param: gen1<any>): any'.
2 ответа
Сигнатуры конструктора в интерфейсах не могут быть реализованы в классах. Это по замыслу. Из документации:
При работе с классами и интерфейсами полезно помнить, что класс имеет два типа: тип статической стороны и тип стороны экземпляра. Вы можете заметить, что если вы создаете интерфейс с сигнатурой конструкции и пытаетесь создать класс, реализующий этот интерфейс, вы получаете ошибку:
interface ClockConstructor { new (hour: number, minute: number); } class Clock implements ClockConstructor { currentTime: Date; constructor(h: number, m: number) { } }
Это потому, что когда класс реализует интерфейс, проверяется только сторона экземпляра класса. Поскольку конструктор находится в статической стороне, он не включен в эту проверку.
Вместо этого вам нужно будет работать непосредственно со статической стороной класса. В этом примере мы определяем два интерфейса: ClockConstructor для конструктора и ClockInterface для методов экземпляра. Затем для удобства мы определяем функцию конструктора createClock, которая создает экземпляры типа, который передается ей.
interface ClockConstructor { new (hour: number, minute: number): ClockInterface; } interface ClockInterface { tick(); } function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface { return new ctor(hour, minute); } class DigitalClock implements ClockInterface { constructor(h: number, m: number) { } tick() { console.log("beep beep"); } } class AnalogClock implements ClockInterface { constructor(h: number, m: number) { } tick() { console.log("tick tock"); } } let digital = createClock(DigitalClock, 12, 17); let analog = createClock(AnalogClock, 7, 32);
Поскольку первый параметр createClock имеет тип ClockConstructor, в createClock (AnalogClock, 7, 32) он проверяет, что AnalogClock имеет правильную сигнатуру конструктора.
Связанное обсуждение: https://github.com/Microsoft/TypeScript/issues/8917
Возможно ли иметь дженерики в конструкторе?
Да
но получаю ошибку
Причина в том, что gen<T>
отличается от T
Fix
interface gen<T> {
constructor(param: T);
}
class genImpl implements gen<any> {
constructor(param: any) {
}
}
То есть используйте any
там, где когда-либо T
использовали. (вы сделали ошибку, поместив T
в gen<any>
и any
)
Похожие вопросы
Новые вопросы
generics
Обобщения являются формой параметрического полиморфизма, встречающейся в ряде языков, включая языки .NET, Java, Swift и Rust.