我必须将页面结构传递给我的核心对象,然后通过自动补全在其中使用这些页面。这是我的工作案例:
interface Adapter{}
interface PageInterface{}
type PageCtor = {new(adapter: Adapter): PageInterface}
class BasePage implements PageInterface{
constructor(public adapter: Adapter) {}
}
class LoginPage extends BasePage{
name: string = 'login'
foo: number
constructor(public adapter: Adapter) {
super(adapter)
}
go() {
console.log('Yo, logged in')
}
}
class LogoutPage extends BasePage{}
class AboutPage extends BasePage{}
class PagesConfig {[key: string]: PageCtor}
type BaseCore<T> = {[key in keyof T]?: T[key]}
class Core<T>{
pages: BaseCore<T> = {}
constructor(public adapter: Adapter, pages: PagesConfig) {
Object.entries(pages).map(([key, value]: [string, PageCtor]) => {
(this.pages as any)[key] = new value(adapter)
})
}
}
interface Pages{
login: LoginPage
logout: LogoutPage
about: AboutPage
}
class CurrentPages{
[key: string]: PageCtor
login = LoginPage
logout = LogoutPage
about = AboutPage
}
const adapter = {} as Adapter
const core = new Core<Pages>(adapter, new CurrentPages())
在这种情况下,我的Core
类的最终用户应提供Pages
接口和CurrentPages
类,它们看起来像是重复之王。每当我班的最终用户需要添加新页面时,他都应该在两个位置添加它。仅使用CurrentPages
类或其他方法如何简化呢?
我认为这与BaseCore
类型的签名有关:
type BaseCore<T> = {[key in keyof T]?: T[key]}
在这里,T[key]
是我的情况下的类构造函数,如何将其更改为类实例?
答案 0 :(得分:1)
仅在从CurrentPages
删除索引签名的情况下,才防止重复。索引签名隐藏任何其他成员的映射。
然后可以使用InstanceType
条件类型从类类型获取实例类型:
type BaseCore<T extends Record<string, PageCtor>> = { [key in keyof T]?: InstanceType<T[key]> }
class Core<T extends Record<keyof T, PageCtor>>{
pages: BaseCore<T> = {}
constructor(public adapter: Adapter, pages: T) {
Object.entries(pages).map(([key, value]) => {
(this.pages as any)[key] = new (value as PageCtor)(adapter)
})
}
}
class CurrentPages {
login = LoginPage
logout = LogoutPage
about = AboutPage
}
const adapter = {} as Adapter
const core = new Core(adapter, new CurrentPages())
core.pages.about;
core.pages.login;
core.pages.logon; //err