JS 也支持泛型?

1,202 阅读1分钟

TLDR

答案:JS 支持泛型,归功于注解 @template

背景

从一个实际案例出发,实现一个获取数组任意项的函数。一般写法如下:

注意我们只能被迫写类型 any

// utils.js
/**
 * 返回数组任意一项,功能等同于 `Array.prototype.at`
 * @param {any[]} arr
 * @param {number} index
 * @returns {any}
 */
function at(arr, index) {
  return arr[index < 0 ? length - Math.abs(index) : index]
}

Array.prototype.at 兼容性不好,否则建议使用 arr.at(-1) 获取最后一项

如果是 TS 那我们可以利用泛型,让返回值自动推导类型,我们可以在 TS 中这么写:

// utils.ts
function at<T>(arr: T[], index: number): T {
  return arr[index < 0 ? length - Math.abs(index) : index]
}

让 JS 支持泛型

JS 要是也支持泛型就好了,答案是可以的,只需通过 jsdoc 的 @template 注解:

// utils.js
/**
 * 返回数组任意一项,功能等同于 `Array.prototype.at`
 * @template T
 * @param {T[]} arr
 * @param {number} index
 * @returns {T}
 */
function at(arr, index) {
  return arr[index < 0 ? length - Math.abs(index) : index]
}

我们验证下

const lastElement1 = at([1, 2, 3], -1)

image.png

const lastElement2 = at(['hello', 'world'], -1)

image.png