本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
index.js
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];}
1, 如果传入参数是 null 或 undefined 返回 []
if (value === null || value === undefined) { return []; }
2, 如果传入参数是数组,原参直接返回
if (Array.isArray(value)) { return value; }
3,如果传入参数是数组string类型,则返回[value],
if (typeof value === 'string') { return [value]; }
4, 如果传入参数是_可迭代对象_,则使用_扩展运算符_ 转换为数组
if (typeof value[Symbol.iterator] === 'function') { return [...value]; }
5,其他类型则转换为[value]
return [value];
需要注意的是string类型的,其typeof s[Symbol.iterator] 也等于'function',那为什么没有放到4,是因为string使用..._扩展运算符_会改变其值,比如‘abc’,使用...会变成['a', 'b', 'c']
index.d.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];
嵌套类型匹配
typescript 使用extends表示条件判断,就像 if 语句一个道理,可以无限嵌套。下面写一个:根据值类型,获取值类型名称的函数类型(这也是官方给的例子):
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T0 = TypeName<string>; // "string"
type T1 = TypeName<"a">; // "string"
type T2 = TypeName<true>; // "boolean"
type T3 = TypeName<() => void>; // "function"
type T4 = TypeName<string[]>; // "object"
迭代器模式(Iterable)
学到了什么
-
可迭代对象本身或原型链上实现了
[Symbol.iterable]方法,可以根据typeof obj[Symbol.iterable] === "function"判断是否是可迭代对象 -
使用条件类型可以描述输入类型与输出类型之间的关系。
文章: