TypeScript 类、泛型的使用实践记录 | 青训营

56 阅读2分钟

TypeScript 泛型

泛型是一种强大的工具,可以增加代码的灵活性和安全性。泛型允许我们在定义类、函数或接口时使用参数化类型,这样就可以在使用这些构造时指定具体的类型。

场景

函数泛型
泛型接口
对象字面量泛型
泛型类

使用方法

  1. 函数泛型
function reverse<T>(items: T[]): T[] {
  return items.reverse();
}
const numbers: number[] = [1, 2, 3, 4, 5];
const reversedNumbers: number[] = reverse(numbers);
console.log(reversedNumbers); // 输出: [5, 4, 3, 2, 1]

const strings: string[] = ["hello", "world"];
const reversedStrings: string[] = reverse(strings);
console.log(reversedStrings); // 输出: ["world", "hello"]

在上面的例子中,reverse 函数使用了泛型类型参数 T,它表示数组中元素的类型。通过使用泛型,我们可以传入不同类型的数组,并获得相应类型的反转数组作为返回值。

  1. 接口中使用泛型
interface Pair<T, U> {
  first: T;
  second: U;
}

const pair: Pair<number, string> = {
  first: 42,
  second: "hello"
};

console.log(pair.first); // 输出: 42
console.log(pair.second); // 输出: "hello"

在上面的例子中,Pair 接口使用了泛型类型参数 T 和 U,分别表示第一个和第二个元素的类型。通过使用泛型,我们可以定义具有不同类型元素的键值对。

  1. 类中使用泛型
class Box<T> {
  private item: T;

  constructor(item: T) {
    this.item = item;
  }

  getItem(): T {
    return this.item;
  }
}

const numberBox: Box<number> = new Box(42);
console.log(numberBox.getItem()); // 输出: 42

const stringBox: Box<string> = new Box("hello");
console.log(stringBox.getItem()); // 输出: "hello"

在上面的例子中,Box 类使用了泛型类型参数 T,它表示盒子中存储的元素的类型。我们可以在创建实例时指定具体的类型,并使用 getItem 方法来获取存储的元素。

  1. 对象字面量泛型
let foo: { <T>(arg: T): T }
 
foo = function <T>(arg:T):T {
   return arg
}
 
foo(123)

这段代码定义了一个变量 foo,它是一个具有泛型函数类型的变量。函数类型具有一个类型参数 T,并接受一个参数 arg,返回类型为 T

然后,我们将一个函数赋值给 foo 变量。这个函数也是一个泛型函数,它接受一个参数 arg,并返回相同的值 arg

最后,我们调用 foo 函数,并传入参数 123。由于参数的类型是 number,在这种情况下,泛型类型参数 T 会被推断为 number。因此,函数会返回参数 123

泛型约束

使用keyof操作符获取T类型的所有键,它的返回 类型是联合 类型

function prop<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}

使用extends继承联合类型

应用

使用ts实现axios底层逻辑(xhr)


const axios={
    get<T>(url:string):Promise<T>{
        return new Promise((resolve,reject)=>{
            let xhr:XMLHttpRequest=new XMLHttpRequest()
            xhr.open('GET',url)
            xhr.onreadystatechange=()=>{
                if(xhr.readyState==4&&xhr.status==200){
                    resolve(JSON.parse(xhr.responseText))
                }
            }
            xhr.send(null)
        })
    }
}
interface Data{
  message:string,
  code:number
}
axios.get<Data>('./data.json').then(res=>{
    console.log(res.code);
})