TypeScript/TS入门学习5

63 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

泛型类

定义一个泛型类如下,基本上和接口定义一样。


class Person<T1, T2>{
    name: T1;
    age: T2;
    sex: T1;
    constructor(name: T1, age: T2, sex: T1) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

使用泛型类的方式如下

  1. 直接用,让编辑器为我们推断出类型即可,下面两个都不会报错,所以最终结果还是不太如意。
const p1 = new Person('使得棒', 18, '男')
const p2 = new Person(12, 18, 12)
  1. 使用类型,最终目的还是为了尽可能多的合理的类型,而不是一些会使程序报错的类型也存在,所以ts推荐我们用下面的方式使用泛型类,明确的告诉编辑器,我们的泛型类型,这样代码的可读性非常棒,因为假如这些参数都是变量的话,不标注类型很难区分的
const p3 = new Person<string, number>('使得棒', 18, '男')
const p4: Person<string, number> = new Person('石头', 10, '中性')


使用类型参数进行约束

首先定义为一个接口,约束这个对象的key必须是sting,值可以是any,随后定义一个getProps方法,此方法接收两个参数,一个是IkeyInterface类型的对象,另一个是string,感觉二者有联系,又联系不到,最终目的是根据第二个参数获取第一参数里的某个属性,但是第一个参数里的属性是有限的。string是任意的,如例子,读取'a''b'都能正确读取到,但是读取'c'就读不到了,这是不符合预期的,编译器也并不会报错。这里就要使用参数约束来解决

interface IKeyInterface {
    [key: string]: any
}
let getProps = (obj: IKeyInterface, key: string): any => {
    return obj[key];
}

let x: IKeyInterface = { a: 1, b: 2 };

let aValue = getProps(x, 'a');
let bValue = getProps(x, 'b');
let cValue = getProps(x, 'c');
console.log(aValue, bValue, cValue);

使用<T, K extends keyof T>,来约束参数之间的 关系,就是说第二个参数必须是第一个参数的key,才能使用这个函数,简单明了,必然能得到预期的结果。

interface IKeyInterface {
    a: any;
    b: any;
}
function getProps<T, K extends keyof T>(obj: T, key: K): any {
    return obj[key];
}


let x:IKeyInterface = { a: 1, b: 2 };

let aValue = getProps(x, 'a');
let bValue = getProps(x, 'b');
let cValue = getProps(x, 'c');
console.log(aValue, bValue, cValue);

这里getProps(x,'c')编辑器报错

image.png