作者:Cri_Hello | 来源:互联网 | 2023-09-24 13:21
我正在打字稿中创建静态方法工厂函数。我在ES6中做到了。它工作正常,并得到了我期望的结果。当我在TypeScript中使用它时,存在类型转换问题。您能帮忙解决这个问题还是建议其他设计?
Javascript
REPL: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
TypeScript
REPL: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 = Exclude
const controllers: COntrollers= {
'event': EventController,'message': MessageController
}
function factory>(controller: K,method: M): Controllers[K][M] {
return controllers[controller][method]
}
const createEvent = factory('event','create')
const readMessage = factory('message','read')
const bool = createEvent()
Demo
简要说明
// 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 = Exclude
// 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
建议