TypeScript tree typization

170 Views Asked by At

Below is a short example of a tree

interface TemplateRoot extends Template {}

class Template {
  #root: TemplateRoot | undefined

  get root (): TemplateRoot {
    return this.#root ?? this
  }

  set root (root: TemplateRoot | undefined) {
    this.#root = root
  }
}

class ChildOne extends Template {
  constructor (root?: Template) {
    super()
    this.root = root
  }

  method (): TemplateRoot {
    // do something
    console.log('Called method of ChildOne')
    return super.root
  }
}

class ChildTwo extends Template {
  constructor (root?: Template) {
    super()
    this.root = root
  }

  method (): TemplateRoot {
    // do something
    console.log('Called method of ChildTwo')
    return super.root
  }
}

class Parent extends Template {
  public $one: ChildOne
  public $two: ChildTwo

  constructor (root?: Template) {
    super()
    this.root = root

    this.$one = new ChildOne(this.root)
    this.$two = new ChildTwo(this.root)
  }

  method (): TemplateRoot {
    // do something
    console.log('Called method of Parent')
    return super.root
  }
}

When calling any method on a child instance it returns a parent instance (if exists) or itself. Nesting and sequence of instances in tree can be different. But they all extend the Template class and return the instance that was passed on creation, else it returns itself (even if it is a child element). Below is an example of usage:

const $parent = new Parent()
$parent.method()
$parent.$one.method().$two.method().method()

The JS code is correct and works fine. But TS compiler doesn't see tree nodes. For example, it doesn't see $two child, when calling $parent.$one.method().$two or $parent.method().$two

How to write correct typization for the tree?

0

There are 0 best solutions below