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)
const lastElement2 = at(['hello', 'world'], -1)