The front will be inevitable in the development of communication with the API, ideally, we can directly in the front-end code defines the API data types, such front-end code can be used directly, but, ideal to ideal, the actual process, the API returns the data structure of the front end directly using the data structure of taste not exactly the same, for example:

// API returns data: [{name: 'zhangsan', sex: 'male',},] // Front-end definition type: interface User {name: string, gender: string,}Copy the code

This is the first problem, there are often different names for the same field, and the reason for this may be, of course, different naming conventions, different API systems or versions, we would be a little bit pushed by the nose if we wanted to define the type of the front segment completely according to the API for convenience. Of course, an easy way to do this is to write a convert method:

class User {
  name: string;
  gender: string;
  
  constructor(json: any) {
    Object.assign(this, json);
    this.gender = json.sex;
  }
  
  toJson() {
  	return ({
      ...this,
      sex: this.gender
    });
  }
}
Copy the code

Of course, you can even define two types: apiUser and User, and then manually maintain the map relationship between the two.

The most lazy thing to do is define a type as what the API looks like.

One of the problems with this solution is that we need to do the same work every time, write a piece of logic that we don’t know why we need to write, but, in essence, it is the conversion relation of a=> B name, and we have to write a=> B, b=> A manual conversion every time. It takes time and effort.

Is there a possibility that I could just describe the relationship between a and B in User, and the method would automatically help me do that conversion. Of course you can.

First of all, we know that the interface is lost at runtime, only has a hint effect on TS during compilation, and becomes unknowable when compiled into JS. So, we basically have to define it by class. So how do you describe a field in class that corresponds to a field in JSON?

Those familiar with Angular are probably familiar with Decorators, which effectively help us add additional information to classes, functions, and properties. Here’s an example:

class User {
  name: string;
  
  @bindJsonProp('sex')
  gender: string;
}
Copy the code

So, we just need to add a line to make it clear that gender and sex correspond. The rest of the transformation relationship can be assigned to a separate method:

const user = convertToType(User)(jsonData);

// ...
// ...

const jsonData = convertToJson(user);
Copy the code

Of course, we can even do type conversions, such as:

String: class User {name! : string; @bindJsonProp({ name: 'sex'}) gender! : string; @bindJsonProp({ typeConverter: dateStringConverter }) date! : Date; }Copy the code

For those interested, take a look at the implementation here: github.com/winfa/ts-js…

The above.