Jeff Tian
Jeff Tian

Reputation: 5923

How to refactor this constructor?

I made a TypeScript class AccessToken, which is to convert the plain object to a class:

export class AccessToken implements IAccessToken {
  public readonly access_token: string
  public readonly created_at: number
  public readonly expires_in: number
  public readonly refresh_token: string
  public readonly scope: string
  public readonly token_type: string | undefined
  public readonly consented_on: number | undefined
  public readonly refresh_token_expires_in: number | undefined

  constructor(data: IAccessToken) {
    this.access_token = data.access_token
    this.created_at = data.created_at
    this.expires_in = data.expires_in
    this.refresh_token = data.refresh_token
    this.scope = data.scope
    this.token_type = data.token_type
    this.consented_on = data.consented_on
    this.refresh_token_expires_in = data.refresh_token_expires_in

    R.difference(R.keys(data), ['access_token', 'created_at', 'expires_in', 'refresh_token', 'scope', 'token_type', 'consendted_on', 'refresh_token_expires_in']).forEach(element => {
      this[element] = data[element]
    });
  }

  public isValid() {...}

  ...
}

The code is ugly. But if I deleted the this.xxx = data.xxx, then the compiler will say Property xxx has no initializer and it not definitely assigned in the constructor.

enter image description here

But write them line by line is stupid.

Can anyone show a better constructor? Thanks in advance!

Upvotes: 1

Views: 408

Answers (2)

John Smith
John Smith

Reputation: 1110

Don't create unnecessary abstraction on data structure.

I suggest you drop this class :)

You're trying to add another abstraction (complexity) on data structure, using the wrapper class.

There is no benefits with your approach. At the end you will have the class which breaks Single Responsibility Principle. IAccessToken is just a data structure.

All you need are just algorithms.

export interface IAccessToken {

}

export class AccessTokenValidator {
    isValid(token: IAccessToken): boolean {
        // ...
    }
}

export function validateAccessToken(token: IAccessToken): boolean {
       // ...
}

Upvotes: 2

Kasabucki Alexandr
Kasabucki Alexandr

Reputation: 630

You can try like this (using Object.assign method):

export class AccessToken implements IAccessToken {
      public readonly access_token!: string
      public readonly created_at!: number
      public readonly expires_in!: number
      public readonly refresh_token!: string
      public readonly scope!: string
      public readonly token_type: string | undefined
      public readonly consented_on: number | undefined
      public readonly refresh_token_expires_in: number | undefined

      constructor(data: IAccessToken) {
        Object.assign(this, data);
      }

  public isValid() {...}

  ...
}

Upvotes: 1

Related Questions