Есть ли тип "Класс" в машинописном тексте? И включает ли это "любое"?
В Java вы можете дать класс методу в качестве параметра, используя тип "Класс". Я не нашел ничего подобного в документах типов документов - возможно ли передать класс методу? И если да, то типа "any" включают такие типы классов?
Предпосылки: У меня проблема с Webstorm, говоря мне, что я не могу передать класс @ViewChild(...)
в Angular 2. Однако компилятор TypScript не жалуется. Подпись @ViewChild()
кажется "Type<any> | Function | string"
, поэтому я задаюсь вопросом, включает ли какой-либо класс или нет.
Ответы
Ответ 1
Эквивалентом того, что вы спрашиваете в машинописном шрифте, является тип { new(): Class }
, например:
class A {}
function create(ctor: { new(): A }): A {
return new ctor();
}
let a = create(A); // a is instanceof A
(код на детской площадке)
Приведенный выше код будет разрешать только классы, конструктор которых не имеет аргументов. Если вы хотите любой класс, используйте new (...args: any[]) => Class
Ответ 2
Угловая внутренняя декларация Type
как:
export interface Type<T> extends Function { new (...args: any[]): T; }
С TypeScript3 должно быть возможно добавлять типы для аргументов без перегрузки функций:
export interface TypeWithArgs<T, A extends any[]> extends Function { new(...args: A): T; }
Пример:
class A {}
function create(ctor: Type<A>): A {
return new ctor();
}
let a = create(A);
Ответ 3
Можно ли передать класс методу? И если да, то типа "any" включают такие типы классов?
Да и да. any
включает в себя все типы.
Вот пример типа, который включает только классы:
type Class = { new(...args: any[]): any; };
Затем, используя его:
function myFunction(myClassParam: Class) {
}
class MyClass {}
myFunction(MyClass); // ok
myFunction({}); // error
Вы не должны пропускать ошибку в классе для Function
хотя это должно работать нормально:
var func: Function = MyClass; // ok
Ответ 4
Type<T>
из @angular/core
является подходящим интерфейсом для класса.
export interface Type<T> extends Function {
new (...args: any[]): T;
}
Вы можете использовать его для сохранения ссылки на класс вместо экземпляра этого класса:
private classRef: Type<MyCustomClass>;
или же
private classRef: Type<any>;
Согласно истории вашего вопроса с @ViewChild
:
@ViewChild позволяет вводить "string selector"
/Component
/Directive
Подпись Type<any> | Function | string
Type<any> | Function | string
Type<any> | Function | string
- это абстрактная подпись, которая позволяет нам внедрять все вышеперечисленное.
Ответ 5
Это должно работать - delcare type
Тип
// just two different classes
class MyClass {}
class OtherClass {
constructor(protected IsVisible: boolean) {}
}
// here we declare our type named "Type"
type Type = Function;
// we will consume just params of a Type (classes)
function take(type: Type){
}
// build will fail
take(1); // not a Type
take("A") // not a Type
take(new Date()); // not a Type
// will be working
take(MyClass); // this is a type
take(OtherClass); // this is a type
Существует рабочий пример
Или аналогичный с интерфейсом
// just two different classes
class MyClass {}
class OtherClass {
constructor(protected IsVisible: boolean) {}
}
// here we declare our type named "Type"
interface Type extends Function {}
// we will consume just params of a Type (classes)
function take(type: Type){
}
// build will fail
take(1); // not a Type
take("A") // not a Type
take(new Date()); // not a Type
// will be working
take(MyClass); // this is a type
take(OtherClass); // this is a type
Пример здесь
Ответ 6
Простейшим решением будет let variable: typeof Class
.
Вот пример:
class A {
public static attribute = "ABC";
}
function f(Param: typeof A) {
Param.attribute;
new Param();
}
f(A);
Ответ 7
Модели наследования в Java и JavaScript различны. В Java у вас есть объект класса, общий для всех экземпляров класса. JavaScript использует прототипное наследование, и нет такой вещи, как объект класса.
И TypeScript, и ES6 имеют ключевое слово класса только синтаксический сахар без изменения модели наследования исполняемого кода.