The definition of generics

Addresses the reuse of classes, interface methods, and support for non-specific data types

Generic function

function getData(value: string) :string {
    return value;
}
Copy the code

Only string data can be returned

If you want to return both string and number, you can define type any

But any is equivalent to abandoning type checking, and the type of the passed parameter and the type of the returned parameter can be inconsistent

function getAnyData(value: any) :any {
    return value;
}
Copy the code

With generics, the type passed in must be the same as the type returned

function getTData<T> (value:T) :T{
    return value;
}
// Specify that the argument must be of the type inside <>
getTData<number> (123);
getTData<string> ('4545');
Copy the code

A generic class

For example, a return minimum algorithm needs to support returning both numbers and strings through the generics of the class

Common implementation:

class MinClass {
    list:number[] = [];
    add(num:number) {
        this.list.push(num);
    }
    min():number {
        let min:number = this.list[0];
        this.list.forEach((item:number) = > {
            if(item<min){ min = item; }})returnmin; }}var m = new MinClass();
m.add(25);
m.add(21);
m.add(13);
m.add(12);
console.log(m.min());
Copy the code

You can only pass in the number type and return the number type.

Implementation of generics:

class MinClass<T> {
    list:T[] = [];
    add(num:T):void {
        this.list.push(num);
    }
    min():T {
        let min = this.list[0];
        this.list.forEach((item) = > {
            if(item < min){ min = item; }})returnmin; }}// Instantiate the class and specify the type represented by T of the class
var m2 = new MinClass<string> (); m2.add('a');
m2.add('c');
m2.add('b');
m2.add('d');
console.log(m2.min());
Copy the code

You can specify different types at instantiation time

A generic interface

Review the common function interface

interface ConfigFn{
    (value:string.value2:string) :string;
}
var setData: ConfigFn = function(value:string,value2:string) :string {
    return value+value2;
}
Copy the code

Generic function interface

The first way to write it

interface ConfigFn{
    <T>(value:T):T;
}
var getData: ConfigFn = function<T> (value:T) :T {
    return value;
}
getData<string> ('12346')
// getData
      
       (12346); // Error
      
Copy the code

The second way to write it

interface ConfigFn<T>{
    (value:T):T;
}
function getData<T> (value:T) :T {
    return value;
}
// Specify a generic type of string when calling this interface
var myGetData:ConfigFn<string>=getData;
myGetData('15')
myGetData(15);// Error
Copy the code

Generic classes that take classes as arguments

class Article {
    title: string | undefined;
    desc: string | undefined;
    status: number | undefined;
    id: number | undefined;
}

class  DB {
    add(info: Article):boolean{
        console.log(info);
        return true; }}let db = new DB();
let news = new Article();
news.title = "China";
news.desc = "Chinese";
news.status = 1;
console.log(db.add(news))
Copy the code

To avoid calling add and passing in different types of arguments that need to be modified, use generics

class  DB2<T> {
    add(info: T):boolean{
        console.log(info);
        return true;
    }
    update(info:T,id:number) :boolean{
        info['id'] = id;
        console.log(info);
        return true; }}// 
      
validates incoming data
let db2 = new DB2<Article>(); db2.add(news) Copy the code

Classes are defined as parameters to constrain the type passed in. Calls to add of different classes only need to specify the type to be passed at instantiation time, without changing the parameter type of add.

class ArticleCate {
    titleCate: string |undefined;
    descCate: string |undefined;
    statusCate: number |undefined;
    idCate:number|undefined;

    constructor(params:{
        titleCate: string |undefined,
        descCate: string |undefined, statusCate? :number |undefinedidCate? :number |undefined
    }){
        this.titleCate = params.titleCate;
        this.descCate = params.descCate;
        this.statusCate = params.statusCate; }}var ac = new ArticleCate({
    titleCate: 'China'.descCate: 'China desc'
});
// Pass the class as a parameter to the generic class. The generic class validates the passed parameters
let db3 = new DB2<ArticleCate>();
console.log(db3.add(ac))// ArticleCate {title: "China", desc: "China desc", status: undefined}
console.log(db3.update(ac,123))// ArticleCate {title: "China", desc: "China desc", status: undefined, id: 123}
Copy the code