【源码共读 第33期】arrify 转数组

196 阅读2分钟

arrify 源码解析

功能:接受一个任意参数,返回一个传入参数为元素的数组,传入集合,则直接返回

  1. 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 迭代器属性,此处不展开描述,可以点击了解 迭代器 自行了解

  1. 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 条件语句中待推断的类型变量

这篇文章写得很不错,大家可以学习一下 点这里

思考

  1. TS 中的 string 是 String 的子类型,但是当前没有处理String,是不是有意为之
  2. 对 TS 现阶段还是了解的阶段,只能日常简单实用,没有知其所以然,需要继续学习