>
TypeScript精通指南
从基础到高级,全面掌握TypeScript开发
下载PDF
TypeScript基础
TypeScript简介与优势
TypeScript是JavaScript的超集,提供类型系统和工具支持,旨在提高开发效率与代码质量。 967字
基本数据类型与类型注解
基本数据类型有number、string、boolean等。类型注解用于指定变量、函数参数和返回值的类型。 1262字
函数与类型推断
定义函数并指定参数和返回值的类型,提高代码可读性和可维护性。涵盖基础函数定义、类型推断、高级类型应用等内容。 1081字
类与面向对象编程
TypeScript中,类实现面向对象编程,包括构造函数、属性、方法、访问修饰符等。封装数据操作,支持继承和多态,提高代码组织和管理效率。 901字
泛型编程基础与进阶
复制

泛型基础

泛型(Generics)是TypeScript中一种特殊的类型,它允许我们创建可重用的组件,这些组件可以适应任何数据类型。泛型的基本语法是在组件名称后使用尖括号 < > 包围类型参数。

例如,我们可以定义一个泛型函数,该函数接受两个参数,并返回它们的和:

function add<T>(x: T, y: T): T {
  if (typeof x === 'number' && typeof y === 'number') {
    return x + y;
  }
  return '无法相加';
}

console.log(add<string>('Hello', 'World')); // 输出: '无法相加'
console.log(add<number>(1, 2)); // 输出: 3

在上面的例子中,<T> 是泛型参数,表示这个函数可以适用于任何类型。

泛型约束

为了增强类型的安全性,TypeScript 提供了泛型约束。这意味着我们可以限制泛型参数的类型。例如,我们可以创建一个泛型函数,它接受一个对象和一个键,然后返回这个对象上该键的值。

interface Lengthwise {
  length: number;
  [prop: string]: any;
}

function getLength<T extends Lengthwise>(obj: T): T['length'] {
  return obj.length;
}

console.log(getLength({ length: 5, a: 'hello' })); // 输出: 5

在上面的例子中,T extends Lengthwise 表明泛型参数 T 必须是 Lengthwise 类型或 Lengthwise 的子类型。

泛型与类型别名

泛型可以与类型别名一起使用,以创建可复用的类型。例如,我们可以定义一个泛型接口,表示一个映射:

type MapObj<T, U> = {
  [key: string]: T;
} & {
  (): U;
};

const myMap: MapObj<number, string> = () => 'Hello';

console.log(myMap['1']); // 输出: undefined
console.log(myMap()); // 输出: 'Hello'

在上面的例子中,MapObj 是一个泛型接口,它定义了一个对象,该对象有字符串键和对应的值,以及一个返回 U 类型值的函数。

泛型与类

泛型也可以用于类,以实现代码复用。例如,我们可以定义一个泛型类,用于创建不同类型的栈:

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

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

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

const intStack = new Stack<number>();
intStack.push(1);
intStack.push(2);
console.log(intStack.pop()); // 输出: 2

const strStack = new Stack<string>();
strStack.push('Hello');
strStack.push('World');
console.log(strStack.pop()); // 输出: 'World'

在上面的例子中,Stack 是一个泛型类,它使用泛型参数 T 来定义栈中元素的类型。

泛型的高级用法

泛型在TypeScript中还有很多高级用法,例如递归泛型、条件类型、映射类型等。这些功能可以让我们更灵活地使用泛型,创建更复杂的组件和类型。

递归泛型

递归泛型允许泛型类型引用自己。例如,我们可以创建一个泛型接口,表示一个嵌套的数组:

type NestedArray<T> = T | (Array<NestedArray<T>>>;

const arr: NestedArray<number> = [1, [2, [3, 4]]];

条件类型

条件类型允许我们根据某些条件选择类型。例如,我们可以创建一个函数,它根据参数的类型返回不同的类型:

type IsString<T> = T extends string ? T : never;

type Result = IsString<number>; // Result 类型为 'never'
type Result2 = IsString<'hello'>; // Result2 类型为 'hello'

映射类型

映射类型允许我们对对象的每个属性应用一个函数。例如,我们可以创建一个函数,它接受一个对象,并返回一个新的对象,其中每个属性的值都被包装在一个数组中:

type Mapper<T> = {
  [P in keyof T]: [T[P]];
};

type Result = Mapper<{ a: number, b: string }>;
// Result 类型为 { a: [number]; b: [string]; }

在上面的例子中,Mapper 是一个映射类型,它接受一个对象 T,并返回一个新的对象,其中每个属性的值都被包装在一个数组中。

总结

泛型是TypeScript中一种强大的工具,它允许我们创建可重用的组件,这些组件可以适应任何数据类型。泛型可以与类型别名、接口、类一起使用,以实现代码复用。通过泛型约束、递归泛型、条件类型、映射类型等高级用法,我们可以更灵活地使用泛型,创建更复杂的组件和类型。

上一章:字面量类型与索引签名 下一章:类型守卫与类型断言详解
吉ICP备2024023809号-2
打赏支付,即可开始下载
应付金额:1元
支付平台选择: