SET001
SET001

Reputation: 11728

typescript: reference current class type

Is it possible to reference current class type in type signature? so that I can do something like this:

 export class Component{
  constructor(config?: { [field in keyof self]: any }) {
      Object.assign(this, config)
  }
}

the idea is to pass a configuration object that would consist of current class keys.

I could go with interfaces but then I need to type same portion of code twise (in interface and in implementing class)

Another way would be to use generics. Something like this:

export class Component<T>{
  init(config?: { [field in keyof T]?: any }) {
    Object.assign(this, config)
  }
}

class TestComponent extends Component<TestComponent>{
  foo: number
}
const component = new TestComponent().init({ foo: 11 })

But having code like class TestComponent extends Component<TestComponent> makes me to search for better ways...

Upvotes: 7

Views: 3658

Answers (2)

smnbbrv
smnbbrv

Reputation: 24581

Doesn't this just work?

export class Component {
  test = 123;

  constructor(config?: { [field in keyof Component]: any }) {
      Object.assign(this, config)
  }
}


new Component({ test: 123 }) // valid
new Component({ test1: 123 }) // invalid

Playground

Even shorter would be simple (thanks to duck typing)

constructor(config?: Component) {

Maybe not really expressing what you want to say / not strict enough, but works.

Even the following is valid

constructor(config = <Component>{}) {

which directly gives you an empty object as the initial value.

Source: abusing this since TypeScript v1.

Upvotes: -2

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

You can reference the current class using polymorphic this type

export class Component{
  init(config?: { [field in keyof this]?: this[field] }) {
    Object.assign(this, config)
  }
}

class TestComponent extends Component{
  foo: number
}
const component = new TestComponent().init({ foo: 11 })
const component2 = new TestComponent().init({ foo: "11" }) // err

You can't however use this as a type in the constructor

export class Component{
  constructor(config?: { [field in keyof this]?: this[field] }) { // error
    Object.assign(this, config)
  }
}

Upvotes: 12

Related Questions