#typescript
#typescript
Вопрос:
Я должен передать структуру страниц моему основному объекту, а затем сделать эти страницы доступными там с автозаполнением. Вот мой рабочий пример:
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
class или каким-либо другим способом?
Я думаю, что это как-то связано с BaseCore
подписью типа:
type BaseCore<T> = {[key in keyof T]?: T[key]}
T[key]
в моем случае это будет конструктор класса, как мне изменить его на экземпляр класса?
Ответ №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
Комментарии:
1. похоже, это работает даже с подписью индекса в
CurrentPages
— imgur.com/a/H5FLoor