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

90 阅读3分钟

前言

TypeScript 是 JavaScript 的一个超集,为 JavaScript 添加了静态类型。而泛型又是 TypeScript 中一种强大的特性,它可以让我们在定义函数、类或接口时定义类型参数。这使得代码更加灵活。在这篇文章里,我将用一些简单的实例来介绍 TypeScript 中的泛型使用方法和场景,以及如何使用类型约束来增加代码的灵活性和安全性。

实践实例

  1. 使用泛型创建通用的数据结构

有时候,我们可能需要一个通用的数据结构,例如栈、队列或链表等。在这种时候使用泛型可以使这些数据结构更加灵活和可重用。

class Stack<T> {
  items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }
}

const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 2

const stringStack = new Stack<string>();
stringStack.push('hello');
stringStack.push('world');
console.log(stringStack.pop()); // 'world'

在这个例子中,我先是创建了一个名为Stack的泛型类。类型参数T表示它可以处理多种类型的数据。Stack类包含一个用于存储元素的items数组属性,以及pushpop两个方法。push方法接受一个类型为T的参数,并将其添加到items数组中。pop方法返回items数组的最后一个元素,并将其从数组中删除。

  1. 使用泛型实现通用的函数

泛型也可以用于定义通用函数,这些函数可以处理多种类型的输入。类型参数可以使函数更具可重用性和灵活性

function identity<T>(arg: T): T {
  return arg;
}

const number = identity<number>(42);
const string = identity<string>('hello');
console.log(number); // 42
console.log(string); // 'hello'

在这串代码中,首先,我定义了一个名为identity的泛型函数,这个函数接受了一个类型为T的参数arg,并且返回了相同的参数。我们通过为identity函数提供类型参数来创建特定类型的函数实例,如numberstring。这使得函数能够在编译时确保类型安全,并避免潜在的类型错误。

  1. 使用泛型和类型约束实现更强大的功能

泛型类型约束允许我们在日常使用泛型的时候使用特定类型或具有特定接口的类型。这有助于提高代码的灵活性和安全性。

interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

const numberArray = [1, 2, 3, 4];
const stringArray = ['hello', 'world'];

loggingIdentity(numberArray); // 4
loggingIdentity(stringArray); // 2

在这个例子中,我使用T extends Lengthwise类型约束,确保只有具有length属性的类型才能作为泛型参数。

  1. 在类上使用泛型

泛型也可以用于类的定义,使其能够处理多种类型的属性和方法。

class GenericClass<T> {
  constructor(private prop: T) {}

  getProp(): T {
    return this.prop;
  }

  setProp(value: T): void {
    this.prop = value;
  }
}

const numberClass = new GenericClass<number>(42);
console.log(numberClass.getProp()); // 42
numberClass.setProp(43);
console.log(numberClass.getProp()); // 43

const stringClass = new GenericClass<string>('hello');
console.log(stringClass.getProp()); // 'hello'
stringClass.setProp('world');
console.log(stringClass.getProp()); // 'world'

在这个例子中,我创建了一个名为GenericClass的泛型类,类型参数T表示它可以处理多种类型的数据。我们定义了一个构造函数,接受一个类型为T的参数prop,并把它赋给私有属性this.prop。我们还定义了两个方法:getPropsetPropgetProp方法返回类型为T的属性prop,而setProp方法接受一个类型为T的参数value,并将其赋给私有属性this.prop

总结

总而言之,泛型是 TypeScript 中的一种强大特性,它的使用增加了代码的通用性和可扩展性。例如:我通过编写了一个组件用来处理输入或输出,这样就不用为了为每种类型重复编写代码。泛型允许我们在定义函数、类、接口和类型别名时使用一个或多个类型参数来表示那些在使用时才确定的类型,从而实现代码的重用和模块化。而类型约束可以对泛型参数进行一些限制,确保在处理特定类型的数据时,我们始终处理具有预期属性和方法的数据,提高代码的灵活性和稳定性。