Which will be better declaration go to with TypeScript? This is a simple question, but during my migration to TypeScript, I'm seeing that in many cases my code could take these two directions... which one could be a better direction to go with: class.ts or interface.ts?

class.ts

export class ActionSet {   
  constructor(private name: string) {}

  get ACTION(): string {
    return this.name;   
  }

  get PENDING(): string {
    return `${this.name}_PENDING`;   
  }

  get FULFILLED(): string {
    return `${this.name}_FULFILLED`;   
  }

  get REJECTED(): string {
    return `${this.name}_REJECTED`;   
  }
}

export function createActionSet(name: string): ActionSet {   
  return new ActionSet(name); 
}


interface.ts

export interface IActionSet {
  ACTION: string;
  PENDING: string;
  FULFILLED: string;
  REJECTED: string;
}

export function createActionSet(name: string): IActionSet {
  return {
    ACTION: name,
    PENDING: `${name}_PENDING`,
    FULFILLED: `${name}_FULFILLED`,
    REJECTED: `${name}_REJECTED`
  };
}


Due to ActionSet is not being used in many places, will it be worth to create a class for it? or is this implementation an overkill?
Your question is a bit too abstract. Both ways are okay in different scenarios. You may even have a mixture of two patterns in the same code base... Sorry, but yes, my answer is "it depends".

I think, the key here is the intent and the way it's conveyed via code. If ActionSet's behavior is rigid, and "known in advance", you may want to declare it as a class (as in first example). This will make sure that even when an instance is created NOT by using createActionSet() it still obeys the same behavior rules.

If however, your entity is not rigid and you don't know all its possible usages in advance, it's probably better to start with an interface and a set of factory functions (as in second example).



Since the context of the question is not really known, I hesitate to go beyond this explanation and recommend a particular one.

In my practice interfaces have always been "handier", more refactorable, and easier to deal with. I do pick them as defaults today and rarely go to classes. This, however, is mostly true to DTO-alike classes ("dummy" classes with little to no behavior whatsoever). I find it helpful to separate the data transfer entities from the data processing entities, but it (again) could be due to the client-server-comm saturated nature of my applications.

Use your own judgement! :)