如何获得类实例类型签名

时间:2019-04-11 09:17:16

标签: 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类或其他方法如何简化呢?

我认为这与BaseCore类型的签名有关:

type BaseCore<T> = {[key in keyof T]?: T[key]}

在这里,T[key]是我的情况下的类构造函数,如何将其更改为类实例?

1 个答案:

答案 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