本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。
源码地址
源码解析
这次的源码几乎没有所谓难度,全然是对于传入参数的类型作判断,而后返回相应数组。
export default function arrify(value) {
if (value === null || value === undefined) {
return [];
}
if (Array.isArray(value)) {
return value;
}
if (typeof value === 'string') {
return [value];
}
if (typeof value[Symbol.iterator] === 'function') {
return [...value];
}
return [value];
}
其中最为主要的是最后一个if处理对于具备iterator可迭代的value作数组转化,在ES6相关实现中,使用「...」就可以将其转化为数组。
这个库如此简单,在此结束好像有种啥都没讲的感觉。而TS相关的文件也很简单,其声明文件:
export default function arrify<ValueType>(
value: ValueType
): ValueType extends (null | undefined)
? [] // eslint-disable-line @typescript-eslint/ban-types
: ValueType extends string
? [string]
: ValueType extends readonly unknown[]
? ValueType
: ValueType extends Iterable<infer T>
? T[]
: [ValueType];
声明文件中对ValueType及参数的类型作了检验。整个arrify为一个泛型声明,根据valueType的判断返回一个数组。结构上与index.js实现的判断一致。
这里我稍微不理解的是(TS小白),对于unknown数组类型,前面为何要加readonly来约束只读,在测试文件声明中有这么一条,所以是约束arrify传递的数组不允许更改?
expectError(arrify(['🦄'] as const).push(''));