Recently reviewed the foundation to see the Learning Typescript this book, opened to learn, found a lot of knowledge, in this record.

Object-oriented programming

The principle of SOLID

There are five considerations for object-oriented programming with Typescript, known simply as the “SOLID” principles

  • Single Responsibility Principle (SRP): States that software components (functions, classes, modules) must focus on a single task (with only a single responsibility)
  • Open/closed principle (OCP): indicates that software must always be designed with an eye to possible evolution (extensibility), but that the program must evolve with minimal modification of existing code (closed to existing changes)

– Richter substitution principle (LSP): indicates that any class in a program can be replaced by another class as long as it inherits the same interface. After the replacement is complete, no additional working procedures are required to run as before. – Interface isolation principle (ISP): indicates that very large interfaces should be broken down into more specific interfaces so that clients only need to care about the interfaces they need. – Dependency Reversal principle (DIP): indicates that a method should comply with the concept of relying on an abstraction (interface) rather than an instance (class). Write a class in Typesciript that looks like this:

   class Person{
       public name: string;
       public surname: string;
       public email: string;
       constructor(name: string, surname: string, email: string){
           this.email = email;
           this.name = name;
           this.surname = surname;
       }
       greet(){
           alert("hello"); }}var p : Person = new Person("liming"."li"."[email protected]");
Copy the code

If we want to validate the email format, adding code to Person would make the Person class very large. We can isolate the email abstraction into a single class, which illustrates the first principle of single responsibility.

class Email{
    public email: string;
    constructor(email: string){
        if(this.validateEmail(email)){
            this.email = email
        }else{
            throw new Error("Invalid email!")}}private validateEmail(email: string){
        var re = '/\S+@\S+\.\S+/';
        return re.test(email)
    }
}
class Person{
       public name: string;
       public surname: string;
       public email: Email;
       constructor(name: string, surname: string, email: string){
           this.email = email;
           this.name = name;
           this.surname = surname;
       }
       greet(){
           alert("hello"); }}Copy the code

In the object-oriented process, there are some relationships between classes, such as association, aggregation, composition, inheritance, mixing, and so on. Instead of introducing their concepts, I will introduce generic classes and generic constraints

A generic class

Generic classes, like generic functions, can introduce a lot of repetitive code. Let’s start with a class

There is oneUserClass and oneNotGenericUserRepositoryThis is a class that gets a list of users and passes it to a JSON file. This is a different class when we want to get a meeting, or a list of songsGenericRepositoryClasses are overridden, and you can use generic classes. As follows:

Sometimes we need generic constraints, as in the example above, and the new requirement is to add some changes to validate data requested through Ajax:

success: (data) = >{
    var list: T[]
    varitems = <T[]>data.items for(let i=0; i<items.length; If (items[I].isValid()){// validates //... } } resolve(list) }Copy the code

We can write a validation interface that constrains generics:

class User implements ValidatableInterface{
    public name: string
    public password: string
    constructor(name: string, password: string){
        this.name = name
        this.password = password
    }
    public isValid(){
        // ...
        return true}}class Talk implements ValidatableInterface{
    public name: string
    constructor(name: string, password: string){
        this.name = name
    }
    public isValid(){
        // ...
        return true}}class NotGenericUserRepository<T extends ValidatableInterface>{
    private _url: string
    constructor(url: string){
        this._url = url
    }
    public getAsync(){
        return new Promise((resolve: (users: T[]) => void. reject) = > {
            $.ajax({
                url: this._url,
                type: "GET".dataType: "JSON".success: (data) = >{
                    var list: T[]
                    varitems = <T[]>data.items for(let i=0; i<items.length; i++){ if(items[i].isValid()){ list.push(items[i]) } } resolve(list) }, error: (e)=>{ reject(e) } }) }) } }class User implements ValidatableInterface{ public name: string public password: string constructor(name: string, password: string){ this.name = name this.password = password } public isValid(){ // ... return true } } class Talk implements ValidatableInterface{ public name: string constructor(name: string, password: string){ this.name = name } public isValid(){ // ... return true } } class NotGenericUserRepository<T extends ValidatableInterface>{ private _url: string constructor(url: string){ this._url = url } public getAsync(){ return new Promise((resolve: (users: T[]) => void. reject) => { $.ajax({ url: this._url, type: "GET", dataType: "JSON", success: (data)=>{ var list: T[] var items = <T[]>data.items for(let i=0; i<items.length; i++){ if(items[i].isValid()){ list.push(items[i]) } } resolve(list) }, error: (e)=>{ reject(e) } }) }) } }Copy the code

The new operation in generics

To create a new object in code, we need to declare that the generic T has a constructor. This means we need to use type: {new() :T; } substitution type: T