TypeScript泛型工作原理详解

 更新时间:2024年02月29日 08:26:28   作者:Moment  
TypeScript 凭借其强大的类型系统,提供了一项称为泛型的功能,它使开发人员能够编写可重用和类型安全的代码,泛型允许您创建可以处理多种类型(而不是单个类型)的组件,本文深入探讨了 TypeScript 泛型,提供了详尽的解释和代码示例来说明它们的用法和好处

什么是泛型?

TypeScript 中的泛型允许编写可处理各种数据类型的代码,同时保持类型安全。它们允许在不牺牲类型检查的情况下创建可重用的组件、函数和数据结构。

泛型由类型参数表示,这些参数充当类型的占位符。这些参数在尖括号 ( <> ) 中指定,可以在整个代码中用于定义变量类型、函数参数、返回类型等。

TypeScript 泛型用例

泛型的基本用法

让我们从泛型函数的简单示例开始:

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

const output = identity<string>("hello");
console.log(output); // hello

在此示例中, identity 是一个采用类型参数的泛型函数 T 。参数 arg 的类型为 T ,函数的返回类型也是 T 。调用 identity<string>("hello") 时,类型参数 T 推断为 string ,确保类型安全。

如何使用泛型类

泛型不仅限于函数,它们还可以与类一起使用。请考虑以下泛型 Box 类示例:

class Box<T> {
  private value: T;

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

  getValue(): T {
    return this.value;
  }
}

const box = new Box<number>(42);
console.log(box.getValue()); //  42

这里, Box 是一个带有类型参数的泛型类 T 。构造函数采用 type 的值,该 getValue 方法返回 type T T 的值。创建 的实例时 Box ,它只能存储和返回 类型的 number 值。

如何对泛型应用约束

有时,您可能希望限制可用于泛型的类型。TypeScript 允许您使用 extends 关键字指定对类型参数的约束。让我们看一个例子

interface Lengthwise {
  length: number;
}

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

const result = loggingIdentity("hello");
console.log(result); // Output: hello

在此示例中,该 loggingIdentity 函数采用一个类型参数, T 该参数必须扩展 Lengthwise 接口,从而确保具有 arg length 属性。此约束允许在不导致编译错误的情况下访问 length 该属性。

如何将泛型与接口一起使用

泛型还可以与接口一起使用,以创建灵活且可重用的定义。请看以下示例:

interface Pair<T, U> {
  first: T;
  second: U;
}

let pair: Pair<number, string> = { first: 1, second: "two" };
console.log(pair); // Output: { first: 1, second: "two" }

这里, Pair 是一个具有两个类型参数 T 和 的接口,分别表示 first 和 second U 属性的类型。声明 pair 为 Pair<number, string> 时,它强制要求属性必须是数字,并且 first second 属性必须是字符串。

如何将泛型函数与数组一起使用

function reverse<T>(array: T[]): T[] {
  return array.reverse();
}

let numbers: number[] = [1, 2, 3, 4, 5];
let reversedNumbers: number[] = reverse(numbers);
console.log(reversedNumbers); // Output: [5, 4, 3, 2, 1]

在此示例中,该 reverse 函数采用 type T 的数组,并返回相同类型的反向数组。通过使用泛型,该函数可以处理任何类型的数组,从而确保类型安全。

如何将泛型约束与 keyof

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

let person = { name: "John", age: 30, city: "New York" };
let age: number = getProperty(person, "age");
console.log(age); // Output: 30

在这里,该 getProperty 函数接受一个 type 的对象和一个 type T K 的键,其中 K 扩展了 T 的键。然后,它从对象返回相应的属性值。此示例演示如何在访问对象属性时使用泛型 keyof 来强制实施类型安全性。

如何使用泛型实用程序函数

function toArray<T>(value: T): T[] {
  return [value];
}

let numberArray: number[] = toArray(42);
console.log(numberArray); // Output: [42]

let stringArray: string[] = toArray("hello");
console.log(stringArray); // Output: ["hello"]

该函数将类型的 T 单个值转换为包含该 toArray 值的数组。这个简单的实用函数展示了如何使用泛型来创建可重用的代码,这些代码可以毫不费力地适应不同的数据类型。

如何将泛型接口与函数一起使用

interface Transformer<T, U> {
  (input: T): U;
}

function uppercase(input: string): string {
  return input.toUpperCase();
}

let transform: Transformer<string, string> = uppercase;
console.log(transform("hello")); // Output: HELLO

在此示例中,我们定义了一个 Transformer 接口,其中包含两个类型参数 T 和 U ,分别表示输入和输出类型。然后,我们声明一个函数 uppercase 并将其分配给 类型的 Transformer<string, string> 变量 transform 。这演示了如何使用泛型来定义函数的灵活接口。

总结

无论是函数、类还是接口,泛型都为构建可伸缩和可维护的 TypeScript 应用程序提供了可靠的机制。理解和掌握泛型可以显著提高您编写高效且无错误的代码的能力。

以上就是TypeScript泛型工作原理详解的详细内容,更多关于TypeScript泛型的资料请关注脚本之家其它相关文章!

相关文章

  • javascript跨域的方法汇总

    javascript跨域的方法汇总

    JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。这里把涉及到跨域的一些问题简单地整理一下
    2015-10-10
  • 一文详解DOM的概念和常用操作

    一文详解DOM的概念和常用操作

    本文详细介绍了DOM的概念和常用操作,文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容,感兴趣的朋友可以参考阅读本文
    2023-04-04
  • JavaScript程序开发之JS代码放置的位置

    JavaScript程序开发之JS代码放置的位置

    JavaScript在页面中使用,那么这些JS代码应该放在什么位置呢?接下来通过本文一起学习吧
    2016-01-01
  • WebGL高级变换之Matrix4使用介绍

    WebGL高级变换之Matrix4使用介绍

    这篇文章主要为大家介绍了WebGL高级变换之Matrix4使用介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 浏览器缓存技术实现浅析

    浏览器缓存技术实现浅析

    这篇文章主要为大家介绍了浏览器缓存技术实现浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Blazor实现微信的Tab切换功能

    Blazor实现微信的Tab切换功能

    这篇文章主要介绍了Blazor实现微信的Tab切换功能,本文中的UI组件使用的是MASA Blazor,您也可以是其他的UI框架,这个并不影响实际的运行效果,本文案例是兼容PC和Android的,演示效果是android中执行的,在PC中执行效果依然有效,需要的朋友可以参考下
    2023-01-01
  • JavaScript拖拽、碰撞、重力及弹性运动实例分析

    JavaScript拖拽、碰撞、重力及弹性运动实例分析

    这篇文章主要介绍了JavaScript拖拽、碰撞、重力及弹性运动实现方法,涉及JavaScript数学运算结合时间函数实现运动效果的相关技巧,需要的朋友可以参考下
    2016-01-01
  • js控制多图左右滚动切换效果代码分享

    js控制多图左右滚动切换效果代码分享

    这篇文章主要介绍了js控制多图左右滚动切换效果,很实用的代码,推荐给大家,有需要的小伙伴可以参考下。
    2015-08-08
  • input type=file 选择图片并且实现预览效果的实例

    input type=file 选择图片并且实现预览效果的实例

    下面小编就为大家带来一篇input type=file 选择图片并且实现预览效果的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 单击按钮显示隐藏子菜单经典案例

    单击按钮显示隐藏子菜单经典案例

    单击按钮实现显示隐藏子菜单很经典的一个案例,接下来为您呈现代码,需要了解的朋友可以参考下
    2013-01-01

最新评论