Open3
【typescript】クラス自体を変数で扱う
クラス自体とは。
class A {
a: string;
constructor(a: string) {
this.a = a;
}
}
のA
のこと。インスタンス化していないクラスそのもの。
名前自体がいまだによく分かっていない(コンストラクタ関数?)
staticや動的インスタンス化などで使いたいが、その時のメモ(まとめたら記事にするかもしれない)
変数に代入してみる
普通に変数に代入しようとすると、エラーが出る。
const classA: A = A; // Property 'a' is missing in type 'typeof A' but required in type 'A'.
書いていて気がついたが、エラーで型書いてあった[1]。typeof Aと書くことで代入することが出来る。
ちなみに、この型には、Aを継承したクラスも代入できる。
class B extends A {
b: string;
constructor(a: string, b: string) {
super(a);
this.b = b;
}
}
const classA: typeof A = A; // OK
const classB: typeof A = B; // OK
-
const classA: A = A;
とは書けないなぁ、どうやって書くことが出来るんだろう?という考えが先に来てコード書くより先に調べてた。 ↩︎
変数に代入できるかを判定する
今度は逆に、クラス自体を変数に入れるために、与えられたクラスがAを継承しているかどうかを判定する。
これを判定する方法を調べたところ、prototypeを使うことで判定することが出来る。
function checkClass(targetClass: any) { // targetClassはクラス自体
if (targetClass.prototype instanceof A) {
console.log("targetClass is an instance of A or its subclass");
} else {
console.log("targetClass is not an instance of A or its subclass");
}
}
checkClass(A); // targetClass is not an instance of A or its subclass...?
checkClass(B); // targetClass is an instance of A or its subclass
checkClass(class C {}); // targetClass is not an instance of A or its subclass
これでいけると思ったが、checkClass(A)
の結果がelse文の方になった。
調べたところ、prototypeは継承元を参照するためのプロパティであるため、本体であるAのprototypeにAは存在しないからtrueにならない。
ではどうやって判定するかというと、、、まだ分かっていない。
とりあえず思いつくのは直接比較する。
function checkClass(targetClass: any) {
if (targetClass === A || targetClass.prototype instanceof A) {
console.log("targetClass is an instance of A or its subclass");
} else {
console.log("targetClass is not an instance of A or its subclass");
}
}
おそらく他の方法がある、気がする。