使劲卷TypeScript进阶二–泛型和命名空间

这是我参与更文挑战的第13天,活动详情查看: 更文挑战

一、泛型

泛型的定义:

泛型是指在定义函数、接口或类的时候,不预先指定具体类型,而在使用的时候再指定类型的一种特性,比如定义一个带有参数的函数,未来在调用函数时,传入值的类型不确定,有可能是string,也有可能是number,这时可以使用泛型来解决问题

  • 例子:写方法时未规定传入和返回的是什么类型的数组,用泛型代替, 执行的时候根据传入的参数决定是什么类型
function arrayFunc<T>(length:number,value:T):Array<T> {
    let arr = []
    for (let index = 0; index < length; index++) {
        arr[index] = value
    }
    return arr
}

let arr:string[] = arrayFunc<string>(3,'张三')
let arrN:number[] = arrayFunc<number>(3,7667)
console.log(arr);
console.log(arrN);

复制代码

image.png

  • 多个参数例子
// 2. 多个参数
function arrayFunc2<T,K>(name:T,age:K):[T,K] {
    return [name,age]
}

let arr:[string,number] = arrayFunc2('张三',18)

console.log(arr);
复制代码

image.png

2.接口泛型

interface IcreateFunc{
    <T>(name:string,age:T):string
}

let func:IcreateFunc = function<T>(name:string, age:T) {
    return name +age
}

let res = func('张三',18)
console.log(res);

复制代码

image.png

3.接口泛型在类中的使用

interface Person<T> {
    name: string
    age: number
    getUserInfo: () => T
}

class userInstance implements Person<string> {
    name: string
    age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
    getUserInfo = () => `姓名: ${this.name}  年龄:  ${this.age}`
}

let person = new userInstance('张三',18)
let userStr = person.getUserInfo()
console.log(userStr);
复制代码

image.png

二、泛型类

泛型类是指在定义类时,为类中的属性或方法定义泛型类型,在创建类的实例时,再指定特定的泛型类型

// 1. 泛型类
class Amount<T>{
    public num!: T
    public total(price:T,count:T) {
        return Number(price) * Number(count)
    }
}

// 参数是数值时
let amount1 = new Amount<number>()
amount1.num = 5
let totalPrice1 = amount1.total(10, amount1.num)
console.log(totalPrice1,'totalPrice1');


// 参数是字符串时
let amount2 = new Amount<string>()
amount2.num = '6'
let totalPrice2 = amount2.total('10', amount2.num)
console.log(totalPrice2,'totalPrice1');
复制代码

image.png

三、泛型约束

泛型约束是指确保泛型类使用的参数是提供特点方法的类型, 比如直接对一个泛型参数使用length属性或者push方法, 会报错, 因为这个方法根本不知道它有这个属性或方法, 使用泛型约束可以解决这个问题.

interface ISchema {
    push: Function
    length: number
}

function setV <T extends ISchema>(data:T, value:any) {
    data.push(value)
    console.log(data);
    console.log(data.length);
}

setV([1,2,3],'4')
复制代码

image.png

四、命名空间

命名空间主要用于组织代码,避免命名冲突, 解决重名的问题, 在代码量较大的情况下,为避免各种变量名相冲突,可以将相似功能的函数、类、接口等放置命名空间内,typescirpt的命名空间使用namespace关键字创建,可以将代码包裹起来,如果需要在外部访问命名空间内部的类或是接口,则需要在类和接口上添加export关键字

用namespace声明一块作用域, 用export导出

namespace A {
    export let message:string = '大家好'
    export function func() {
        console.log(`我是函数中消息 ${message}`);
    }
    export class person {
        name:string = '王五'
        sayHello() {
            console.log(`姓名: ${this.name} 说你好`);        
        }
    }
}

A.func()

let person2 = new A.person()

person2.sayHello()
复制代码

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享