direct

Lesson one: Play with typescript

Lesson two, basic types and introductory advanced types

Lesson three: Generics

Lesson four: Reading advanced types

Lesson 5: What is a namespace

Special, learn typescript in vue3🔥 source 🦕 – “is”

Lesson 6. What is a declare? 🦕 – Global declaration

Insert a lesson

I was going to pick up where I left off with advanced types, but as I went along I realized that there are a lot of places in advanced types that you need to know about generics, so I’m going to plug in a generics section.

What are generic variables and generics?

We all know that a variable can represent any data, and a generic variable can represent any type:

// Declare a generic variable after the function name with "<>"
function convert<T> (input:T) :T{
    return input;
}
Copy the code

The convert parameter is labeled as type T, and the return value is labeled as T, indicating that the input and output of the function are of the same type. A function that uses a generic variable is called a generic function. Is there a generic class?

Note: T is arbitrary. Just like variables, you can call them whatever you like, but it is recommended to use capital letters, such as U/RESULT.

A generic class
class Person<U> {
    who: U;
    
    constructor(who: U) {
        this.who = who;
    }

    say(code:U): string {
        return this.who + ' :i am '+ code; }}Copy the code

Declare a generic variable U after the class name with “<>”. This variable can be used for methods and attributes of the class. Next we use the following generic class:

let a =  new Person<string> ('James Bond');
a.say(007) // The argument should be a string
a.say('007') / / right
Copy the code

We passed in the generic variable (string) to tell ts that U of this class is a string. By definition of Person, we know that the argument to say is also a string, so a.say(007) will return an error because 007 is number. We can constrain generics by passing in generic variables.

Automatically infer the type of a generic variable

We can also omit the generic variable string, since ts can infer that U is of type string from the type of the argument passed in at instantiation:

let a =  new Person('James Bond');
Let a = new Person
      
       (' James Bond ');
      
a.say(007) // The argument should be a string
a.say('007') / / right
Copy the code
Generic method

Methods and functions are defined in the same way:

class ABC{
    // Enter T[] to return T
    getFirst<T>(data:T[]):T{
        return data[0]; }}Copy the code
What is a generic?

To tell you the truth, I have searched the TS document several times, but I did not see his formal definition of generics, only to express it is a description of a variety of types (type range) format, I feel a little abstract, I use my own understanding of the concrete: using dynamic types (generic variables) to describe functions and classes.

The generic type

We can use a generic variable to describe a type (type range). The Array type of TS is itself a generic type, and it needs to pass the specific type to be precise:

let arr : Array<number>;
arr = ['123']; // Error: Array can only have type number
arr = [123];
Copy the code

Let’s define a generic type for the convert function at the beginning:

function convert<T> (input:T) :T{
    return input;
}

// Define generic types
interface Convert {
    <T>(input:T):T
}

/ / verification
let convert2:Convert = convert // No error is reported
Copy the code

A generic interface

Make attributes more flexible by passing in different type parameters:

interface Goods<T>{
    id:number;
    title: string;
    size: T;
}

let apple:Goods<string> = {id:1.title: 'apple'.size: 'large'};
let shoes:Goods<number> = {id:1.title: 'apple'.size: 43};
Copy the code

Extending generic variables (generic constraints)

function echo<T> (input: T) :T {
    console.log(input.name); // Error, T is not determined by the name attribute
    return input;
}
Copy the code

As mentioned above, T can represent any type, but the corresponding type is the base type. Therefore, when we operate on input.name, we need to mark the name attribute on the input. This is equivalent to narrowing the scope of generic variables and restricting generics:

// now T is a type with a name attribute
function echo<T extends {name:string}>(input: T): T {
    console.log(input.name); / / right
    return input;
}
Copy the code

A generic application, factory function

function create<T.U> (O: {new(): T|U; }) :T|U {
    return new O();
}
Copy the code

I want to talk about 3 points:

  1. Multiple generic variables can be defined.
  2. Generic variables and common type usage have always supported types such as union/cross types.
  3. If a piece of data is instantiable, we can use{new(): any}Said.

Don’t mess with generics

The main purpose of generics is to constrain, or narrow down, types. If you can’t constrain functionality, it means you don’t need generics:

function convert<T> (input:T[]) :number{
    return input.length;
}
Copy the code

It makes no sense to use generics, just like any.

conclusion

Generic type is the most important feature of a compiled language, written by generic code can let a person feel very good, can say is a generic type into hand ts programmers must skilled techniques, the interview is pluses, so you write code using generic practice a lot oh, refueling ヾ (◍ ° ∇ ° ◍) ノ ゙, yes, it is written in ts following several small projects, writing is not good, If you have a passion, you can write better:

Gesture library: github.com/any86/any-t…

Imperative calls to vue components: github.com/any86/vue-c…

Some common code snippets at work: github.com/any86/usefu…

A Mini event manager: github.com/any86/any-e…

WeChat group

Thank you for reading, if you have any questions you can add group 🚀, there are a lot of interesting front end friends in the group, let’s learn and grow together!

You can add my wechat, and I will pull you into the wechat group (Tencent limits the number of people in the wechat group to 100, so I must pull you into the group when the number exceeds 100).