nrako
nrako

Reputation: 3019

Getter / Setter in Typescript without Class

Here is a sampling of SO questions for Typescript getters/setters: from 2015, Jan 2018, Sept 2018, among others.

That said, what is the recommended way for defining Typescript types for getters/setters in a vanilla JS object? That is, I would like a plain old javascript object without the class syntax, and to understand the best practices for typing. Here's the interface -

interface Store {
   activeEvent: Date
}

A few constraints for this object -

No new to instantiate

No duplicates - this doesn't work

const Store: Store = {
  activeEvent: new Date(),
  get activeEvent() {
    return this.activeEvent;
  },
}

No dangling underscores. Airbnb's eslint config is yelling at this -

const Store: Store = {
  _activeEvent: {},
  get activeEvent() {
    return this._activeEvent;
  },

Ideally I would like to have default values (that is, if I drop the key, the error goes away, but on first access activeEvent is undefined). I suppose I could init and return this.activeDate if it is undefined, which works, but get is actually get & set in that scenario -

 get activeDate() {
    if(this.activeDate){ return this.activeDate }
    const date = new Date()
    this.activeDate = date;
    return date;
  },

I would rather not generate duplicate keys with getters and setters just to have getters and setters.

Interestingly enough, the fact that the getter/setter have the same key doesn't error out, it's just when they match the private-ish variable, which makes me think I am doing something wrong. I appreciate any insight.

Error on getter setter

Upvotes: 8

Views: 7682

Answers (1)

suddjian
suddjian

Reputation: 2406

Wrap your object creation in a closure, and keep variables that aren't part of the interface outside the object:

function createStore() {
  let activeEvent = new Date();
  return {
    get activeEvent() {
      return activeEvent;
    },
  };
}

This avoids the name collision/infinite loop issue you're currently running into - the object you return has a .activeEvent getter, but the variable backing it lives outside the object, in the scope of the createStore function.

Upvotes: 9

Related Questions