NO7 Typescript 中的泛型

118 阅读2分钟
/*

泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。

组件不仅能够支持当前的数据类型,也要能支持未来的数据类型,这在创建大型系统是十分便利。

通俗理解: 泛型就是解决类、接口方法的复用性,以及对不特定数据类型的支持

*/

// NO1 同时返回string和number 

// function getData(value:any):any { // 可以用any,但相当于放弃了类型检查

//     return 'hahah'

// }

// getData('12')

// NO2 泛型函数,传入什么返回什么,需要使用泛型(一般用T)

function getData<T>(value:T):T { 

    return value

}

getData<number>(123)

getData<string>('123')

// NO3 泛型类,比如有个最小堆算法,需要同时支持返回数字和字符串(a-z)两种类型。

// class MinClass {

//     public list:number[] = []

//     add(num:number) {

//         this.list.push(num)

//     }

//     min():number {

//         var minNum = this.list[0]

//         for(var i=0; i<this.list.length; i++) {

//             if (minNum > this.list[i]) {

//                 minNum = this.list[i]

//             }

//         }

//         return minNum

//     }

// }

// var m = new MinClass()

// m.add(1)

// m.add(10)

// m.add(9)

// alert(m.min())

class MinClass<T> {

    public list:T[] = []

    add(value:T):void {

        this.list.push(value)

    }

    min():T {

        var minNum = this.list[0]

        for(var i=0; i<this.list.length; i++) {

            if (minNum > this.list[i]) {

                minNum = this.list[i]

            }

        }

        return minNum

    }

}

var m = new MinClass<number>() // 指定了T为number

m.add(9)

m.add(10)

m.add(9)

// alert(m.min())

var s = new MinClass<string>() // 指定了T为string

s.add('z')

s.add('a')

s.add('o')

// alert(s.min())

// NO4 泛型接口

    // 函数类型接口

    // interface Config{

    //     (value: string):string

    // }

    // var setData:Config = function(value:string):string {

    //     return value

    // }

    // alert(setData('zhangsan'))

    // 泛型接口1

    interface Config{

        <T>(value: T):T

    }

    var setData:Config = function<T>(value:T):T {

        return value

    }

    alert(setData<string>('李四'))

    // 泛型接口2

    interface Config2<T>{

        (value: T):T

    }

    function setData2<T>(value: T):T {

        return value

    }

    var myGetData:Config2<string> = setData2

    alert(myGetData('ak'))

// NO5 泛型类的进一步深入:把类作为参数来约束数据传入的类型

/*

    定义一个user类,映射数据库字段

    定义一个mySqlDb类,用于操作数据库

    然后把user类作为参数传入到mySqlDb中

    var user = new User({

        username: '张三',

        password: '1234'

    })

    var db = new MySqlDd()

    db.add(user)

*/

// class User {

//     username: string | undefined

//     password: string | undefined

// }

// class MySqlDd {

//     add(user:User):boolean {

//         console.log(user)

//         return true

//     }

// }

// var u = new User()

// u.username = '张三'

// u.password = '1234'

// var db = new MySqlDd()

// db.add(u)

// ---- 实现文章分类------

// class ArticleCate {

//     title: string | undefined

//     status: number | undefined

// }

// class MySqlDd {

//     add(info:ArticleCate):boolean {

//         console.log(info)

//         return true

//     }

// }

// var b = new ArticleCate()

// b.title = '三国'

// b.status = 1

// var db = new MySqlDd()

// db.add(b)

\


// 上述代码有重复,优化为:

class MySqlDd<T> {

    add(info:T):boolean {

        console.log(info)

        return true

    }

    update(info:T, id:number): boolean {

        console.log(info)

        console.log(id)

        return true

    }

}

 

class User {

    username: string | undefined

    password: string | undefined

}

var u = new User()

u.username = '张三'

u.password = '1234'

var db = new MySqlDd<User>()

db.add(u)

\


class ArticleCate {

    title: string | undefined

    status: number | undefined 

    constructor(params: {

        title: string,

        status?: number

    }) {

        this.title = params.title

        this.status = params.status

    } 

}

var a = new ArticleCate({

    title'三国',

})

a.status = 0

var db1 = new MySqlDd<ArticleCate>()

db1.add(a)

db1.update(a, 12)