はじめに
TypeScriptの型がわからなすぎて困惑している皆さん、こんにちは🏄♂️
今日は、たまに見かけるnew () => T
についてまとめます!
new () => Tの解説
class Dog {
public name = 'ポチ'
bark = () => {
console.log('ワン!')
}
}
const fn1 = (a: new () => Dog) => {
// const fn1 = (a: { new (): Dog }) => { でも可
return new a();
}
fn1(Dog).bark()
fn1(new Dog()).bark() // !! Error !!
fn1()
の引数にインスタンス化する前のクラスDog
を入れることができます。インスタンス(new Dog()
)したものを渡すことはできません。
ユースケースとしては、クラスを関数に渡して、インスタンスを受け取りたい時です。
踏み込んだ解説
const fn2 = (a: typeof Dog) => {
return new a();
}
fn2(Dog).bark()
fn2(new Dog()).bark() // !! Error !!
上記でも同じことができます!
が、公式FAQにはnew ()
を使うように書かれています。なぜならtypeof
はジェネリクスの型に使えないからです。
https://github.com/microsoft/TypeScript/wiki/FAQ#why-cant-i-write-typeof-t-new-t-or-instanceof-t-in-my-generic-function
const fn3 = <T extends Dog>(a: new () => T) => {
return new a();
}
const fn4 = <T extends Dog>(a: typeof T) => { // !! Error !!
return new a();
}
まとめ
Genericsとnew()を組み合わせて使いましょう!というお話でした。
インタスンスを生成するFactory Methodパターンを作る時に、利用する型ですね!
参考
https://qiita.com/ConquestArrow/items/ace6d926b7e89b8f92d9#fnref1
https://teratail.com/questions/184663