如何在 TypeScript 中创建静态方法工厂



我正在打字稿中创建一个静态方法工厂函数。我在 ES6 中做到了。它工作正常,并如我预期的那样得到结果。当我在 TypeScript 中使用它时,存在类型转换问题。你能帮忙解决这个问题或建议不同的设计吗?

JavaScript

注册: https://repl.it/@RenjithV/NeatTepidBugs

class EventController {
static create () {
console.log('event created')
}
}
class MessageController {
static read () {
console.log('message read')
}
}
const controllers = {
'event': EventController,
'message': MessageController
}
function factory (controller, method) {
return controllers[controller][method]() // Working fine
}
const createEvent = factory('event', 'create') // event created
const readMessage = factory('message', 'read') // message read

打字稿

注册: https://repl.it/@RenjithV/EuphoricFeistyUtility

class EventController {
static create () {
console.log('event created')
}
}
class MessageController {
static read () {
console.log('message read')
}
}
const controllers = {
'event': EventController,
'message': MessageController
}
function factory (controller: string, method: string) {
return controllers[controller][method]() // How to fix this? How to create a method factory like this?
}
const createEvent = factory('event', 'create')
const readMessage = factory('message', 'read')
class EventController {
public static create () {
console.log('event created')
return true
}
}
class MessageController {
public static read () {
console.log('message read')
}
}
type Controllers = {
event: typeof EventController
message: typeof MessageController
}
type OnlyStatic<T> = Exclude<T, 'prototype'>
const controllers: Controllers = {
'event': EventController,
'message': MessageController
}
function factory<K extends keyof Controllers, M extends OnlyStatic<keyof Controllers[K]>>(controller: K, method: M): Controllers[K][M] {
return controllers[controller][method]
}
const createEvent = factory('event', 'create')
const readMessage = factory('message', 'read')
const bool = createEvent()

演示

简要说明

// generic calling is not allowed as typescript
// doesn't yet know what arguments you gonna pass to factory
// return actual function instead of function return value
controllers[controller][method]
// extending typescript Exclude utility
// removes prototype key from string union
// because class by default has static prototype method
// Exclude<"some" | "other", "other"> => "some"
type OnlyStatic<T> = Exclude<T, 'prototype'>
// assign keys of Controllers to K
// "event", "message"
K extends keyof Controllers
// assign keys of EventController if K is "event"
// assign keys of MessageController if K is "message"
M extends OnlyStatic<keyof Controllers[K>

建议

最新更新