Skip to content

泛型

上次更新 2024年10月9日星期三 1:45:28 字数 0 字 时长 0 分钟

泛型指使用时才定义类型,即定义可以像参数一样定义,主要解决类,接口、函数的复用性,让他们可以处理多种类型。

基本使用

下面的示例返回值是 any,这不是我们想要的,因为我们想要具体返回类型

ts
function dump(arg: any) {
  return arg;
}
dump(1);
dump("hello");

使用了泛型定义后,返回值即为明确了类型

ts
function dump<T>(arg: T) {
  return arg;
}
dump<string>("hello");

如果调用时不指定类型系统也会自动推断类型

ts
dump("hello"); // string
dump(1); // number

类型继承

下面的代码是不严谨的,我们不需要处理数字,因为数字没有 length 属性,同时我们希望返回的类型不是 any

ts
function getLength(arr: any) {
  return arr.length;
}

getLength([1, 2, 3]); // 3
getLength("hello"); // 5
getLength(1); // undefined

泛型为不确定类型,所以下面没有 length 属性将会报错

ts
function getLength<T>(arr: T[]): number {
  return arr.length;
}

我们可以继承来解决这个问题

ts
function getLength<T extends { length: number }>(arr: T): number {
  return arr.length;
}
// 或者结合 interface 或 type
type LengthType = {
  length: number;
};
function getLength<T extends LengthType>(arr: T): number {
  return arr.length;
}

下面我们来掌握在类中使用泛型的方法

使用泛型复用类

ts
class User<T> {
  constructor(private user: T) {}
  get(): T {
    return this.user;
  }
}
type T = {
  name: string;
  age: number;
};
const user = new User<T>({ name: "John", age: 20 });

接口

下面是接口的类型使用泛型

ts
interface ArticleInterface<T, B> {
  comment: T;
  title: B;
}
class Article<T, B> {
  comment: T;
  title: B;
  constructor(params: ArticleInterface<T, B>) {
    this.comment = params.comment;
    this.title = params.title;
  }
  get() {
    return { comment: this.comment, title: this.title };
  }
}

const article = new Article<string, number>({ comment: "hello", title: 1 });