#typescript #generics
#typescript #общие сведения
Вопрос:
Пожалуйста, рассмотрите следующий код:
class Wrapper<T> {
public static forConstructor<S extends Object>(construc: { new (...args: any[]): S }): Wrapper<S> {
return new Wrapper<S>();
}
}
class A {
private aaa: string = null;
}
class B {
private bbb: string = null;
}
const wrapper: Wrapper<A> = Wrapper.forConstructor(B);// LINE X
Однако в СТРОКЕ X Wrapper<A> = Wrapper<B>
это неверно, TypeScript не показывает ошибку в этой строке. В чем моя ошибка?
Комментарии:
1. В настоящее
Wrapper<A>
время иWrapper<B>
являются структурно совместимыми. Если вы сохраните переданный конструктор как поле (например), вы получите сообщение об ошибке2. @AlekseyL. Я изменил поля, добавил разные методы, конструкторы — не помогло.
3. Я говорю об обертке. Я добавлю пример
Ответ №1:
В настоящее Wrapper<A>
время и Wrapper<B>
являются структурно совместимыми. Если вы сохраните переданный конструктор как поле (например), вы получите сообщение об ошибке:
type Constructor<T> = new (...args: any[]) => T;
class Wrapper<T> {
constructor(private c: Constructor<T>){}
public static forConstructor<T>(construc: Constructor<T>): Wrapper<T> {
return new Wrapper<T>(construc);
}
}
class A {
private aaa: string = null;
}
class B {
private bbb: string = null;
}
const wrapper: Wrapper<A> = Wrapper.forConstructor(B); // error
<a rel="noreferrer noopener nofollow" href="https://www.typescriptlang.org/play/index.html#src=type Constructor = new (…args: any[]) => T;
class Wrapper {
constructor(private c: Constructor){}
public static forConstructor(construc: Constructor): Wrapper {
return new Wrapper(construc);
}
}
class A {
private aaa: string = null;
}
class B {
private bbb: string = null;
}
const wrapper: Wrapper = Wrapper.forConstructor(B); // error» rel=»nofollow noreferrer»>Игровая площадка
Ответ №2:
Статический метод не может использовать аргумент типа экземпляра Wrapper<T>
, поскольку static не ограничен экземпляром. Ваша сигнатура метода <S extends Object
по сути означает any
объект. Таким образом, безопасность типов вообще отсутствует. Вот почему tscompiler не жалуется на
const wrapper: Wrapper<A> = Wrapper.forConstructor(B);// LINE X
Однако, если вы на самом деле используете аргумент типа экземпляра и делаете его нестатическим, он будет жаловаться, например
class Wrapper<S> {
public forConstructor(construc: { new (...args: any[]): S }): Wrapper<S> {
return new Wrapper<S>();
}
}
const wrapper: Wrapper<A> = new Wrapper();
wrapper.forConstructor(B); // will not work
Комментарии:
1.
A static method can not use the instance type argument Wrapper<T> since static is not instance bounded.
конечно, я это знаю. Вот почему общий параметр для класса естьT
, а для статического метода естьS
. И мне нужен только статический метод. Возможно ли это сделать?2. Вы не можете использовать
Wrapper<T>
asT
в своем статическом методе. Итак, нет, это невозможно.