- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与
- 这是源码共读的第33期, 点击了解详情
arrify 源码解析
功能:接受一个任意参数,返回一个传入参数为元素的数组,传入集合,则直接返回
- JS 版本
export default function arrify(value) {
// 处理null或者不传参,默认返回空数组
if (value === null || value === undefined) {
return [];
}
// 本来就是数组就直接返回
if (Array.isArray(value)) {
return value;
}
// 因为 string 也是一个可迭代对象,需要单独处理
if (typeof value === "string") {
return [value];
}
// 处理内置的可迭代对象,判断是否有 Symbol.iterator 属性,且是个函数
// Array Map Set String TypedArray
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
if (typeof value[Symbol.iterator] === "function") {
return [...value];
}
return [value];
}
console.log(arrify(null)); // []
console.log(arrify(undefined)); // []
console.log(arrify("我是字符")); // ['我是字符']
console.log(arrify(88)); // [88]
console.log(arrify({ name: "tom" })); // [{ name: 'tom' }]
console.log(arrify([1, 23, 43])); // [1, 23, 43]
Symbol.iterator 迭代器属性,此处不展开描述,可以点击了解 迭代器 自行了解
- TS 版本
// extends ts 的泛型约束
// infer 类型推断
export default function arrify<ValueType>(
value: ValueType
): ValueType extends (null | undefined) // 如果传入的是 null 或者 undefined 直接返回空数组
? [] // eslint-disable-line @typescript-eslint/ban-types
: ValueType extends string // string 单独处理
? [string]
: ValueType extends readonly unknown[]
? ValueType
: ValueType extends Iterable<infer T> // 如果 ValueType 能赋值给 Iterable<infer T>,也就说是个可迭代对象,则就返回对应的类型集合
? T[]
: [ValueType];
ts 涉及到了泛型、类型约束(extends)、类型推断(infer)
- 开始的 ValueType 类型是一个泛型,用于类型推断的时候传递到后面使用的
- extends 是一个类型约束
ValueType extends (null | undefined)ValueType 是否属于 (null | undefined) 联合类型的子类型 是的话则返回空数组,否则继续下面逻辑 - infer 这个相对复杂一点,表示在
extends条件语句中待推断的类型变量
这篇文章写得很不错,大家可以学习一下 点这里
思考
- TS 中的 string 是 String 的子类型,但是当前没有处理String,是不是有意为之
- 对 TS 现阶段还是了解的阶段,只能日常简单实用,没有知其所以然,需要继续学习