Ty —— 强大而简洁的 Javascript 类型判断库

本文介绍了npmitype库中的Ty工具,用于简洁地判断JavaScript函数参数的类型,包括各种逻辑运算符如is、not、or等的用法,以及如何处理复杂类型判断如空值和Proxy对象。
摘要由CSDN通过智能技术生成
npm i type-yes

项目地址:https://github.com/liutaigang/type-yes

🚀 About

首先通过一个例子来认识下 Ty —— 方法的参数类型判断,如:

function func(value) {
    if( value 为 string 或 number 或 为空 ) {
        ... do something
    }
}

判断方式:

// 方式一:常规版
typeof value === 'string' || typeof value === 'number' || value == null

// 方式二:Lodash 版
_.isString(value) || _.isNumber(value) || _.isNil(value)

// 方式三:Ty 版
Ty(value).str.num.nil.or

Ty 版的判断是最简洁的!!!,但是也会让人有些疑惑——上述表达式:Ty(value).str.num.nil.or,它如何实现判断的?下面分析下:

profile.png

  • 判断参数:需要判断的量,可以是任意类型

  • 类型标识符:类型的“符号”。str—— string,num —— number, nil —— null or undefined

  • 逻辑运算符:最终逻辑运算方式。or —— 或运算

上述表达式可以简单理解为:

// 当 value = 123

[[value, 'str'], [value, 'num'], [value, 'nil']] =判断类型=> [false, true, false] =或运算=> true

到了这里,你大概已经了解 Ty 的逻辑符 or 的使用,除了 or , Ty 还有 is,not,and,nor,nand

🦄 Usage

is

逻辑”是“判断

// 常规
typeof value === 'number'
// Ty
Ty(value).num.is

// Ty error, 当进行 is 判断时,如果判断参数(或判断标识符)输入多个值时,会报错
Ty(value01, value02).num.is // error
Ty(value).num.str.is // error

not

逻辑”否“判断, is 的取反

// 常规
typeof value != 'number'
// Ty
Ty(value).num.not

// Ty error, 当进行 not 判断时,如果判断参数(或判断标识符)输入多个值时,会报错。与 is 判断相同

or

逻辑”或“判断

// 常规
typeof value === 'string' || typeof value === 'number'
// Ty
Ty(value).str.num.or

// 等价于:
Ty(value, value).str.num.or // 参数会自动补全,所以这样写就“没必要”了

nor

逻辑”或非“判断, or 的取反

// 常规
!(typeof value === 'string' || typeof value === 'number')
// Ty
Ty(value).str.num.nor

and

逻辑“与”判断

示例一:

// 常规
typeof value01 === 'string' && typeof value02 === 'number'
// Ty
Ty(value01, value02).str.num.and

示例二:

// 常规
typeof value01 === 'string' && typeof value02 === 'string'
// Ty
Ty(value01, value02).str.and

// 等价于:
Ty(value01, value02).str.str.and // 标识符也会自动补全,所以这样写就“没必要”了

nand

逻辑“与非”判断,and 的取反

// 常规
!(typeof value01 === 'string' && typeof value02 === 'number')
// Ty
Ty(value01, value02).arr.num.nand

上述的判断中,除了所有的逻辑操作符的使用方法,我还认识了 num、str 、nil 等类型标识符。在 Ty 中,类型标识符共有 60+,其中包括:简写类型标识符特殊类型标识符常规类型标识符,下面我们将一一介绍:

简写类型标识符

简写标识符对应的常规标识类实际类型
objobjectObject (这里的 object, 不包含 array 和 null )
arrarrayArray
strstringString
numnumberNumber
boolbooleanBoolean
undefundefinedundefined
funcfunctionFunction

特殊类型标识符

标识符实际类型
nilnull 或 undefined
empty[] 或 {}
emptyobject{} —— 没有任何属性的空对象
emptyarray[] —— 没有任何元素的空数组
NaNNaN
infinityInfinity 无穷大
primitive原始类型: null, undefined, boolean, number, bigint, string, symbol

示例:

// value = Symbol()
const isPrimitive = Ty(value).primitive.is // true

// value = []
const isEmpty = Ty(value).empty.is //true

常规类型标识符

标识符实际类型
nullnull (不包含 undefined)
undefinedundefined
booleanBoolean
numberNumber
stringString
bigintBigInt
symbolSymbol
objectObject (这里的 object, 不包含 array 和 null )
arrayArray
functionFunction
promisePromise
dateDate
regexpRegExp
mapMap
setSet
…更多的请看附录

示例:

// value = new Map()
const isIterator = Ty(value).array.map.set.or // true

// value = 123123123n
cosnt isPrimitive = Ty(value).number.string.bigint.symbol.or // true

🔩 More

扩展的 Ty 的类型标识符

如果已有的类型标识符不满足时, Ty 支持扩展,只要提供一个 TypeMatcher , 即类型匹配器:

type TypeMatcher<T extends string> = (parameter: any, typeFlag: T) => boolean;

示例(ts):

import { Ty, TypeMatcher, TypeFlag, buildinTypeMatcher } from 'type-yes';

type MyType = 'obj_arr_null' | 'finite' | TypeFlag; // TypeFlag 是 Ty 的所有的类型标识符的一个联合类型
const typeMatcher: TypeMatcher<MyType> = (parameter, typeFlag) => {  // parameter —— 判断参数, typeFlag —— 类型标识符
  switch (typeFlag) {
    case 'obj_arr_null':
      return typeof parameter == null;
    case 'finite':
      return Number.isFinite(parameter);
    default:
      return buildinTypeMatcher(parameter, typeFlag); // buildinTypeMatcher —— Ty 内置的类型匹配器
  }
};

const tty = new Ty(typeMatcher);

tty({}).obj_arr_null.is; // true
tty([]).obj_arr_null.is; // true
tty(null).obj_arr_null.is; // true
tty(123).finite.is; // true

使用效果(obj_arr_null 和 finite 会出现在拼写提示中):

截屏2024-03-30 18.53.01.png

Proxy 如何判断

Proxy 类型是难以判断的——Proxy 代理的对象是什么类型,proxy 实例就判定为相应的类型,如:

const arr = ['a', 'b', 'c'];
const arrProxy = new Proxy(arr, {});
typeof arrProxy; // array
Object.prototype.toString.call(arrProxy); // [object Array]

Ty 中,继承 Proxy 实现了一个子类:IdentifiableProxy,这个子类的类型是可以判断的,如:

const arr = ['a', 'b', 'c'];
const arrProxy = new IdentifiableProxy(arr, {});
Object.prototype.toString.call(arrProxy); // [object Proxy-Array]

// 使用 Ty 判断
Ty(arrProxy).proxy.is; // true —— 做 proxy 判断时,arrProxy 判定为 proxy
Ty(arrProxy).array.is; // true —— 做 array 判断时,arrProxy 判定为 array
Ty(arrProxy).array.proxy.and; // true

类型标识符的“否运算“

如何使用 Ty 实现下面这样一个类型判断:

typeof value01 === 'object' && typeof value02 != 'number'

在 Ty 中,可以对单个类型标识符进行否运算:! + 类型标识符,如:

Ty(value01, value02).obj['!num'].and

// 如:
Ty({}, 123).obj['!num'].and // false
Ty({}, 'abc').obj['!num'].and // true

类型标识符的“可为空运算“

如何使用 Ty 实现下面这样一个类型判断:

typeof value01 === 'object' && (typeof value02 === 'number' || value02 == null)

在 Ty 中,可以对单个类型标识符进行可为空运算:? + 类型标识符,如:

Ty(value01, value02).obj['?num'].and

// 如:
Ty({}, 123).obj['?num'].and // true
Ty({}, null).obj['?num'].and // true

🍩 Appendix

常规类型标识符附录

标识符对应类型
errorError
reflectReflect
jsonJSON
mathMath
int8arrayInt8Array
uint8arrayUint8Array
uint8clampedarrayUint8ClampedArray
int16arrayInt16Array
uint16arrayUint16Array
int32arrayInt32Array
uint32arrayUint32Array
bigint64arrayBigInt64Array
biguint64arrayBigUint64Array (en-US)
float32arrayFloat32Array
float64arrayFloat64Array
weakmapWeakMap
weaksetWeakSet
arraybufferArrayBuffer
atomicsAtomics
dataviewDataView
weakrefWeakRef
finalizationregistryFinalizationRegistry (en-US)
iteratorIterator
proxyProxy
intlIntl
intl.collatorIntl.Collator
intl.datetimeformatIntl.DateTimeFormat
intl.displaynamesIntl.DisplayNames
intl.listformatIntl.ListFormat
intl.localeIntl.Locale
intl.numberformatIntl.NumberFormat
intl.pluralrulesIntl.PluralRules
intl.relativetimeformatIntl.RelativeTimeFormat
intl.segmenterIntl.Segmenter
globalnode 环境下的 globalThis
windowwindow 环境下的 globalThis 或 window
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值