build up object[] from raw data set I have a list of raw data like following mockData and need to generate to a object[] format, some key-value pair are required from raw data like first, last, state. but some key-value pair are option like nickname. Eventually, I need to build a object array with some same key-value like raw data, and some key's value depends on another key's value like fullname, address. If there is a better way for me to do it and make it more dynamically? because I will have more than 20 different key-value set like fullname, address that need to be built by some function related on raw data

export const mockData: Human[] = [
  {
    first: 'name1',
    last: 'v1',
    state: 'ny',
  },
  {
    first: 'name2',
    last: 'v2',
    state: 'pa',
    nickname: 'rocketman',
  }]

export interface Human {
  first: string;
  last: string;
  state: string;
  nickname?: string;
}

export interface Student extends Human{
  fullname: string;
  address: string;
}

function setFullName(first: string, last: string): string {
    return `${first} ${last}`
}

function setAddress(first: string, last: string, state: string): string {
    return `${first} ${last} live a ${state}`
}

function buildStudentData(jsons: Human[]): Student[] {
  return jsons.map((json) =&gt;  &lt;Student&gt; {
      first: json.first,
      last: json.last,
      nickname:  json.hasOwnProperty('nickname') ? json.nickname : json.first,
      fullname: setFullName(json.first, json.last),
      address: setAddress(json.first, json.last, json.state)})
}


console.log(buildStudentData(mockData));
You have kind of "logic" in your mapping (nickname, fullname and adress). And I assume that this will be the case also for the other data sets you mentioned. That makes generalizing hard. Especially when there is not much in common.

You COULD write a generator were you can configurate for each attribute the mapping strategy, but this would take more time then write the mapping of those 20-30 values directly.

I personally use in quite some cases classes instead of interfaces and then apply a public static "fromJSON(...)" or in your case "fromHuman(...)" method onto it. Its MORE code to write, but it makes everything explicit. And you are able to ensure that a object (a student) ALWAYS has a proper name. Such things make refactoring later easier. But as i said, the negative part is that you implement more code to gain this safety.

For example in the following code there is only ONE way to create a student. And if the primary identifier of this object (the firstname / lastname combination) is missing then it errors out.

export class Student implements Human {
  readonly first: string;
  readonly last: string;
  state: string;
  nickname?: string;
  fullname: string;
  address: string;

  private constructor(firstname: string, lastname: string{
    if(firstname &amp;&amp; lastname){
      throw Error('Students must have a first and a lastname!');
    }
    this.first = firstname;
    this.last = lastname;
  }

  public static fromHuman(human: Human): Student {
    const student: Student = new Student(human.first, human.last);
    student.state= human.state;
    student.nickname = human.nickname | human.first
    // if you are using TSD 3.7 or above you should use the ?? operator
    // ...
  }
}


If some of the values may change, then i would think about NOT storing calculated values (like the adress) but use a GET method. The reason is, IF one of the values used for calculation (e.g. the state) changes, then a stored "adress" would have to get updated manually.

export class Student ...{
   // ...
   public get adress(): string{
      return `${this.first} ${this.last} live a ${this.state}`
    }
 }
}


PRO: Values get updated automaticly
CON: Values have to get recalculated each time. This may be a performance issue, depending on the usage.

At the end (as always) it depends what you want to achieve. If you need a quick way to generate data, then i would personally stick to your way.
If you are using the objects heavily in your application, then i would think about how they are used from the business perspective (which values may not change, which may change often ,...) and treat them as Business Objects. And then guard the objects against misuse. Even if only you are using that code, this may guard you against mistakes and help you understand your code when you have to fix a bug or add a feature a few months later.