typescript基础篇(三)

119 阅读1分钟

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

泛型:

泛型定义函数:

function log <T>(value: T): T {
    console.log(value);
    return value;
}

类型 T 表示输入和返回值参数是保持一致的。

调用:

1、指定类型;
log<string[]>(['a', 'b']);
2、用ts类型推断;
log(['a','b']);

泛型定义函数类型:

类型别名定义一个泛型函数类型
type Log = <T>(value: T) => T;
let myLog: Log = log;

泛型接口:

interface Log2 {
    <T>(value: T) => T
}
// 这里泛型仅仅约束了函数,我们也可以约束其他成员,如下:
interface Log3<T = string>{
    (value: T): T
}
// 这样接口的其他成员均收到泛型的约束;; T = string表示默认类型
let myLog: Log3<number> = log;
let myLog2: Log3 = log;
myLog(1) // 参数必须是number类型;
myLog2('123') // 参数使用默认类型string;

泛型类与泛型约束:

// 先定义一个泛型类
class Log<T>{
    run(value: T){
        console.log(value);
        return value;
    }
}
// 泛型不能约束类的静态成员;
let log1 = new Log<number>();
log1.run(1); // 传入类型参数,那么只能是传入的类型
let log2 = new Log();
log2.run({a: 1}); 或者 lo2.run('a');
function log<T>(value: T): T{
    console.log(value, value.length); // 这里会提示 T 类型上不存在 length 属性
    return value;
}
可以声明一个接口让 T 继承这个属性,这样就能通过类型检查啦,如下:
interface Length {
    length: number
}    
function log<T extends Length>(value: T): T{
    console.log(value, value.length);
    return value;
}
log([1]); // 数组
log('1234'); // 字符串
log({length: 1}); // 对象

泛型,优点:

函数和类可以轻松地支持支持多种属性,增强程序的扩展性;

不必写多条函数重载,冗长的联合类型,增强代码可读性;

灵活控制类型之间的约束;