🚀
[Typescript] Classの型からインスタンスの型を推論させる方法
結論
class A {
static id: 'A';
}
type InstanceOf<ClassType extends {new (...args: any[]): any; prototype: any;}> = ClassType['prototype']
type X = InstanceOf<typeof A>
// X => Aのインスタンス型
何に使えるか
pluginなどをclass形式で渡す時に使える。以下のコードはPluginによって、本来のライブラリに存在しないメソッドをプラグインのIDにインスタンスを設定することで機能を拡張する例。
type IPlugin<PluginId extends string, PluginType = any> = {
id: PluginId
new (a: any): PluginType
prototype: PluginType
}
type Lib = {
orgMethods: ()=> void
}
function someLib<Plugins extends IPlugin<any,any>[]>(args: any, options:{
plugins?: Plugins
}): Lib & {
[index in Extract<keyof Plugins,number>]: {
[key in Plugins[index]['id']]: InstanceOf<Plugins[index]>
}
}[number] {
const exInstances = options?.plugins?.reduce((current, pluginClass) => {
return {
...current,
[pluginClass.id]: new pluginClass(args),
}
}, {})
return {
orgMethods: () => {},
...exInstances
}
}
class HelloPlugin {
static id: 'hello' = 'hello';
run () {}
}
const foo = someLib({foo: 'foo'},{
plugins: [HelloPlugin]
})
foo.hello.run()
Singletonであれば、もちろんpropertyに型をマッピングしてもよい。
Discussion