vtils:小巧实用的 JavaScript 工具类库

小巧实用的 JavaScript 工具类库。

https://fjc0k.github.io/vtils/

特性

  • 源于日常项目实践,更实用
  • 使用 TypeScript 编写,类型友好
  • 支持摇树优化(Tree Shaking),只引入使用到的工具
  • 浏览器、Node、小程序多端兼容

安装

# yarn
yarn add vtils

# or, npm
npm i vtils --save

使用

在线体验: https://stackblitz.com/edit/vtils

import { inBrowser, shuffle } from 'vtils'

if (inBrowser()) {
  alert('您在浏览器中...')
}

alert(shuffle([1, 2, 3, 4]))

工具列表

:package:
工具函数

:bulb:
assign

源码 | API

分配来源对象的可枚举属性到目标对象上。

来源对象的应用规则是从左到右,随后的下一个对象的属性会覆盖上一个对象的属性。

assign(
  {},
  { x: 1 },
  { y: 2 },
  { x: 5, z: 9 },
)
// => { x: 5, y: 2, z: 9 }

:bulb:
base64Decode

源码 | API

返回 base64 解码后的字符串。

base64Decode('dnRpbHM=') // => vtils
base64Decode('5Lit5Zu9') // => 中国
base64Decode('8J+RqOKAjfCfkrs=') // => :man:‍:computer:

:bulb:
base64Encode

源码 | API

返回 base64 编码后的字符串。

base64Encode('vtils') // => dnRpbHM=
base64Encode('中国') // => 5Lit5Zu9
base64Encode(':man:‍:computer:') // => 8J+RqOKAjfCfkrs=

:bulb:
base64UrlDecode

源码 | API

返回 base64url 解码后的字符串。

base64UrlDecode('dnRpbHM') // => vtils
base64UrlDecode('5Lit5Zu9') // => 中国
base64UrlDecode('8J-RqOKAjfCfkrs') // => :man:‍:computer:

:bulb:
base64UrlEncode

源码 | API

返回 base64url 编码后的字符串。

base64UrlEncode('vtils') // => dnRpbHM
base64UrlEncode('中国') // => 5Lit5Zu9
base64UrlEncode(':man:‍:computer:') // => 8J-RqOKAjfCfkrs

:bulb:
castArray

源码 | API

如果 value 是数组,直接返回;如果 value 不是数组,返回 [value]

castArray([123, 456]) // => [123, 456]
castArray(123) // => [123]
castArray('hello') // => ['hello']
castArray(null) // => [null]

:bulb:
chunk

源码 | API

arr 拆分成多个 size 长度的区块,并将它们组合成一个新数组返回。

如果 arr 无法等分,且设置了 filler 函数,剩余的元素将被 filler 函数的返回值填充。

const arr = [1, 2, 3, 4, 5, 6]
chunk(arr, 2) // => [[1, 2], [3, 4], [5, 6]]
chunk(arr, 3) // => [[1, 2, 3], [4, 5, 6]]
chunk(arr, 4) // => [[1, 2, 3, 4], [5, 6]]
chunk(arr, 4, index => index) // => [[1, 2, 3, 4], [5, 6, 0, 1]]

:bulb:
clamp

源码 | API

返回限制在最小值和最大值之间的值。

clamp(50, 0, 100) // => 50
clamp(50, 0, 50) // => 50
clamp(50, 0, 49) // => 49
clamp(50, 51, 100) // => 51

:bulb:
createURIQuery

源码 | API

创建 URI 查询字符串。

createURIQuery({ x: 1, y: 'z' }) // => x=1&y=z

:bulb:
debounce

源码 | API

创建一个去抖函数,将触发频繁的事件合并成一次执行。

该函数被调用后,计时 wait 毫秒后调用 fn 函数。若在 wait 毫秒内该函数再次被调用,则重新开始计时。

一个应用场景:监听输入框的 input 事件发起网络请求。

document.querySelector('#input').oninput = debounce(
  e => {
    console.log(e.target.value)
  },
  500,
)

:bulb:
defaultTo

源码 | API

检查 value 是否是 nullundefinedNaN ,是则返回 defaultValue ,否则返回 value

defaultTo(1, 2) // => 1
defaultTo(NaN, 2) // => 2
defaultTo(null, 2) // => 2
defaultTo(undefined, 2) // => 2

:bulb:
endsWith

源码 | API

检查 str 是否以 needle 结尾。

endsWith('hello', 'llo') // => true
endsWith('hello', 'he') // => false

:bulb:
fill

源码 | API

使用 value 来填充(替换) arr ,从 start 位置开始, 到 end 位置结束(但不包括 end 位置)。

fill(Array(5), () => 1) // => [1, 1, 1, 1, 1]
fill(Array(3), (value, index) => index) // => [0, 1, 2]

:bulb:
flexible

源码 | API

移动端屏幕适配。

:bulb:
forOwn

源码 | API

遍历对象的可枚举属性。若遍历函数返回 false ,遍历会提前退出。

注:基于你传入的 obj ,遍历函数中 key 的类型可能为 number ,但在运行时, key 始终为 string ,因此,你应该始终把 key 当作 string 处理。(为什么会这样? https://github.com/microsoft/TypeScript/pull/12253#issuecomment-263132208)

forOwn(
  { x: '1', y: 2 },
  (value, key) => {
    console.log(key, value)
  }
)

:bulb:
getGlobal

源码 | API

获取全局对象。

// 浏览器中
getGlobal() // => window
// Node 中
getGlobal() // => global

:bulb:
getType

源码 | API

检测 value 的类型。

getType(1) // => 'Number'
getType(true) // => 'Boolean'
getType([]) // => 'Array'
getType(/hello/) // => 'RegExp'

:bulb:
groupBy

源码 | API

根据 iteratee 返回的值对 data 进行分组。

groupBy(
  [
    { type: 1, name: '石头' },
    { type: 3, name: '花生' },
    { type: 2, name: '鲸鱼' },
    { type: 1, name: '树木' },
    { type: 2, name: '鲨鱼' },
  ],
  item => item.type,
)
// => {
// =>   1: [
// =>     { type: 1, name: '石头' },
// =>     { type: 1, name: '树木' },
// =>   ],
// =>   2: [
// =>     { type: 2, name: '鲸鱼' },
// =>     { type: 2, name: '鲨鱼' },
// =>   ],
// =>   3: [
// =>     { type: 3, name: '花生' },
// =>   ],
// => }

:bulb:
has

源码 | API

检查 key 是否是对象 obj 自身的属性。

const obj = { x: 1, 2: 'y' }
has(obj, 'x') // => true
has(obj, 2) // => true
has(obj, 'toString') // => false

:bulb:
ii

源码 | API

立即调用函数并返回其返回值。

注: ii = immediately invoke

ii(() => 1) // => 1

:bulb:
inAndroid

源码 | API

检查是否在 Android 设备中。

// Android 设备中
inAndroid() // => true
inAndroid(
  () => console.log('你在 Android 设备中'),
)

:bulb:
inBrowser

源码 | API

检查是否在浏览器环境中。

// 浏览器中
inBrowser() // => true
inBrowser(
  () => console.log('你在浏览器中'),
)

:bulb:
inIOS

源码 | API

检查是否在 iOS 设备中。

// iOS 设备中
inIOS() // => true
inIOS(
  () => console.log('你在 iOS 设备中'),
)

:bulb:
inNode

源码 | API

检查是否在 Node 环境中。

// Node 中
inNode() // => true
inNode(
  () => console.log('你在 Node 中'),
)

:bulb:
inRange

源码 | API

检查 value 是否在某区间内。

// 2 是否在区间 (0, 2) 内
inRange(2, 0, 2, InRangeIntervalType.open) // => false

// 2 是否在区间 [0, 2] 内
inRange(2, 0, 2, InRangeIntervalType.closed) // => true

// 2 是否在区间 [0, 2) 内
inRange(2, 0, 2, InRangeIntervalType.leftClosedRightOpen) // => false

// 2 是否在区间 (0, 2] 内
inRange(2, 0, 2, InRangeIntervalType.leftOpenRightClosed) // => true

:bulb:
inWechatMiniProgram

源码 | API

检查是否在微信小程序环境中。

// 微信小程序中
inWechatMiniProgram() // => true
inWechatMiniProgram(
  () => console.log('你在微信小程序中'),
)

:bulb:
inWechatWebview

源码 | API

检查是否在微信浏览器环境中。

// 微信浏览器中
inWechatWebview() // => true
inWechatWebview(
  () => console.log('你在微信浏览器中'),
)

:bulb:
includes

源码 | API

检索值 value 是否在数组 arr 中。

includes([1, 2, 3], 1) // => true
includes([NaN, 2, 3], NaN) // => true
includes([1, 2, 3], 4) // => false

检索可枚举属性值 value 是否在对象 obj 中。

includes({ x: 1, y: 2 }, 1) // => true
includes({ x: 1, y: 2 }, 3) // => false

检索值 value 是否在字符串 str 中。

includes('hello', 'h') // => true
includes('hello', 'll') // => true
includes('hello', '123') // => false

:bulb:
isArguments

源码 | API

检查 value 是否是一个 arguments 对象。

function myFunction() {
  console.log(isArguments(arguments)) // true
}

:bulb:
isArray

源码 | API

检查 value 是否是一个数组。

isArray(['x']) // => true
isArray('x') // => false

:bulb:
isBoolean

源码 | API

检查 value 是否是一个布尔值。

isBoolean(true) // => true
isBoolean(false) // => true
isBoolean('true') // => false

:bulb:
isChineseIDCardNumber

源码 | API

检查 value 是否是合法的中国大陆居民 18 位身份证号码。

isChineseIDCardNumber('123456') // => false

:bulb:
isDate

源码 | API

检查 value 是否是一个日期。

isDate(new Date()) // => true

:bulb:
isEmail

源码 | API

检查 value 是否是一个邮件地址。

isEmail('hello@foo.bar') // => true
isEmail('hello@foo') // => false

:bulb:
isEmpty

源码 | API

检查 value 是否是空值,包括: undefinednull''falsetrue[]{}

isEmpty(undefined) // => true
isEmpty(null) // => true
isEmpty('') // => true
isEmpty(false) // => true
isEmpty(true) // => true
isEmpty([]) // => true
isEmpty({}) // => true

:bulb:
isEqualArray

源码 | API

检查给定的数组的各项是否相等。

isEqualArray([1], [1]) // => true
isEqualArray([1], [5]) // => false

:bulb:
isFinite

源码 | API

检查 value 是否是原始有限数值。

isFinite(1) // => true
isFinite(Infinity) // => false

:bulb:
isFunction

源码 | API

检查 value 是否是一个函数。

isFunction(() => {}) // => true
isFunction(2000) // => false

:bulb:
isHan

源码 | API

检查 value 是否全是汉字。

isHan('hello') // => false
isHan('嗨咯') // => true

:bulb:
isInteger

源码 | API

检查 value 是否是一个整数。

isInteger(1) // => true
isInteger(1.2) // => false
isInteger(-1) // => true

:bulb:
isNaN

源码 | API

检查 value 是否是 NaN

isNaN(NaN) // => true
isNaN(2) // => false

:bulb:
isNegativeInteger

源码 | API

检查 value 是否是一个负整数。

isNegativeInteger(-1) // => true
isNegativeInteger(1) // => false

:bulb:
isNil

源码 | API

检查 value 是否是 nullundefined

isNil(null) // => true
isNil(undefined) // => true

:bulb:
isNull

源码 | API

检查 value 是否是 null

isNull(null) // => true

:bulb:
isNumber

源码 | API

检查 value 是否是一个数字。

注: NaN 不被认为是数字。

isNumber(1) // => true
isNumber(0.1) // => true
isNumber(NaN) // => false

:bulb:
isNumeric

源码 | API

检查 value 是否是一个数值。

注: Infinity-InfinityNaN 不被认为是数值。

isNumeric(1) // => true
isNumeric('1') // => true

:bulb:
isObject

源码 | API

检查 value 是否是一个对象。

isObject({}) // => true
isObject(() => {}) // => true
isObject(null) // => false

:bulb:
isPlainObject

源码 | API

检查 value 是否是一个普通对象。

isPlainObject({}) // => true
isPlainObject(Object.create(null)) // => true
isPlainObject(() => {}) // => false

:bulb:
isPositiveInteger

源码 | API

检查 value 是否是一个正整数。

isPositiveInteger(1) // => true
isPositiveInteger(-1) // => false

:bulb:
isPossibleChineseMobilePhoneNumber

源码 | API

检测 number 是否可能是中国的手机号码。

isPossibleChineseMobilePhoneNumber(18000030000) // => true
isPossibleChineseMobilePhoneNumber(10086) // => false

:bulb:
isPossibleChineseName

源码 | API

检测 value 是否可能是中国人的姓名,支持少数名族姓名中间的 · 号。

isPossibleChineseName('鲁') // => false
isPossibleChineseName('鲁迅') // => true
isPossibleChineseName('买买提·吐尔逊') // => true

:bulb:
isPromiseLike

源码 | API

检查 value 是否像 Promise

isPromiseLike(Promise.resolve()) // => true

:bulb:
isRegExp

源码 | API

检查 value 是否是一个正则对象。

isRegExp(/hello/) // => true
isRegExp(new RegExp('hello')) // => true

:bulb:
isString

源码 | API

检查 value 是否是一个字符串。

isString('') // => true
isString('hello') // => true

:bulb:
isUndefined

源码 | API

检查 value 是否等于 undefined

isUndefined(undefined) // => true
isUndefined(void 0) // => true

:bulb:
isUrl

源码 | API

检查 value 是否是一个有效的网址,仅支持 httphttps 协议,支持 IP 域名。

isUrl('http://foo.bar') // => true
isUrl('https://foo.bar/home') // => true

:bulb:
jestExpectEqual

源码 | API

这是一个 jest 测试辅助函数,等同于 expect(actual).toEqual(expected) ,只不过是加上了类型。

:bulb:
keyBy

源码 | API

根据 iteratee 返回的键对 data 进行分组,但只保留最后一个结果。

keyBy(
  [
    { type: 1, name: '石头' },
    { type: 3, name: '花生' },
    { type: 2, name: '鲸鱼' },
    { type: 1, name: '树木' },
    { type: 2, name: '鲨鱼' },
  ],
  item => item.type,
)
// => {
// =>   1: { type: 1, name: '树木' },
// =>   2: { type: 2, name: '鲨鱼' },
// =>   3: { type: 3, name: '花生' },
// => }

:bulb:
keys

源码 | API

返回 obj 的可枚举属性组成的数组。

注:基于你传入的 obj ,返回的 key 的类型可能为 number ,但在运行时, key 始终为 string ,因此,你应该始终把 key 当作 string 处理。(为什么会这样? https://github.com/microsoft/TypeScript/pull/12253#issuecomment-263132208)

keys({ x: 1, 2: 'y' }) // => ['x', '2'] 或 ['2', 'x']

:bulb:
last

源码 | API

返回数组 arr 的最后一项。

last([1, 2, 3]) // => 3

:bulb:
loadResource

源码 | API

加载图片、代码、样式等资源。

loadResource([
  'https://foo.bar/all.js',
  'https://foo.bar/all.css',
  'https://foo.bar/logo.png',
  {
    type: LoadResourceUrlType.js,
    path: 'https://s1.foo.bar/js/full',
    alternatePath: 'https://s2.foo.bar/js/full',
  },
]).then(() => {
  // 资源加载完成后的操作
})

:bulb:
mapValues

源码 | API

映射对象的可枚举属性值为一个新的值。

mapValues(
  { x: 1, y: 2 },
  value => value + 10,
)
// => { x: 11, y: 12 }

:bulb:
memoize

源码 | API

函数结果缓存。

let i = 0
const fn = memoize(() => i++)
fn() // => 0
fn() // => 0

:bulb:
noop

源码 | API

无操作函数。

noop() // => undefined

:bulb:
omit

源码 | API

创建一个从 obj 中剔除选中的可枚举属性的对象。

omit({ x: 1, y: 2 }, ['x']) // => { y: 2 }

:bulb:
orderBy

源码 | API

允许指定一个或多个规则对数据进行排序。

orderBy(
  ['x', 'xyz', 'xy'],
  {
    iteratee: item => item.length,
    type: OrderByRuleType.desc,
  },
)
// => ['xyz', 'xy', 'x']

:bulb:
padEnd

源码 | API

str 右侧填充字符。

padEnd('姓名', 4, '*') // => 姓名**

:bulb:
padStart

源码 | API

str 左侧填充字符。

padStart('姓名', 4, '*') // => **姓名

:bulb:
parallel

源码 | API

并行执行任务, 同步任务异步任务 皆可。

parallel([
  () => 1,
  async () => 'hello',
]).then(res => {
  // => [1, 'hello']
})

:bulb:
parseCSSValue

源码 | API

解析 CSS 值的数值和单位。

parseCSSValue('12px') // => { value: 12, unit: 'px' }
parseCSSValue(12) // => { value: 12, unit: 'px' }
parseCSSValue('12%') // => { value: 12, unit: '%' }

:bulb:
pick

源码 | API

创建一个从 obj 中选中的可枚举属性的对象。

pick({ x: 1, y: 2 }, ['x']) // => { x: 1 }

:bulb:
placeKitten

源码 | API

给定大小获取占位猫咪图片,图片来自: https://placekitten.com/

placeKitten(100) // => https://placekitten.com/100/100

给定宽高获取占位猫咪图片,图片来自: https://placekitten.com/

placeKitten(100, 200) // => https://placekitten.com/100/200

:bulb:
pluck

源码 | API

将数据中每一项的迭代值组合成一个数组返回。

pluck(
  [{ id: 1, name: 'Jay' }, { id: 2, name: 'Lily' }],
  item => item.name,
) // => ['Jay', 'Lily']

将数据中每一项的迭代值组合成一个对象返回。

pluck(
  [{ id: 1, name: 'Jay' }, { id: 2, name: 'Lily' }],
  item => item.name,
  item => item.id,
) // => { 1: 'Jay', 2: 'Lily' }

:bulb:
randomString

源码 | API

生成一个随机字符串。

randomString() // => m481rnmse1m

:bulb:
range

源码 | API

创建一个包含从 startend ,但不包含 end 本身范围数字的数组。

range(0, 5) // => [0, 1, 2, 3, 4]
range(0, -5, -1) // => [0, -1, -2, -3, -4]

:bulb:
repeat

源码 | API

重复 n 次给定字符串。

repeat('a', 5) // => aaaaa

:bulb:
round

源码 | API

对传入的数字按给定的精度四舍五入后返回。

round(3.456) // => 3
round(3.456, 1) // => 3.5
round(3.456, 2) // => 3.46
round(345, -2) // => 300

:bulb:
roundDown

源码 | API

对传入的数字按给定的精度向下取值后返回。

roundDown(3.456) // => 3
roundDown(3.456, 1) // => 3.4
roundDown(3.456, 2) // => 3.45
roundDown(345, -2) // => 300

:bulb:
roundUp

源码 | API

对传入的数字按给定的精度向上取值后返回。

roundUp(3.456) // => 4
roundUp(3.456, 1) // => 3.5
roundUp(3.456, 2) // => 3.46
roundUp(345, -2) // => 400

:bulb:
safeGet

源码 | API

:bulb:
sample

源码 | API

从数组中随机获取一个元素。

sample([1, 2, 3]) // => 1 或 2 或 3

从对象中随机获取一个可枚举属性的值。

sample({ x: 1, y: 2, z: 3 }) // => 1 或 2 或 3

:bulb:
sequential

源码 | API

顺序执行任务, 同步任务异步任务 皆可。

sequential([
  () => 1,
  async () => 'hello',
]).then(res => {
  // => [1, 'hello']
})

:bulb:
shuffle

源码 | API

打乱一个数组。

shuffle([1, 2]) // => [1, 2] 或 [2, 1]

:bulb:
startsWith

源码 | API

检查 str 是否以 needle 开头。

startsWith('hello', 'he') // => true
startsWith('hello', 'llo') // => false

:bulb:
sum

源码 | API

计算传入值的总和。

sum([1, 2, 3]) // => 6

:bulb:
sumBy

源码 | API

根据 iteratee 返回的结果计算传入值的总和。

sumBy(
  [
    { count: 1 },
    { count: 2 },
    { count: 3 },
  ],
  item => item.count,
)
// => 6

:bulb:
throttle

源码 | API

创建一个节流函数,给函数设置固定的执行速率。

  • 该函数首次被调用时,会立即调用 fn 函数,并记录首次调用时间。
    • 该函数第二次被调用时:
      • 如果该次调用时间在首次调用时间的 wait 区间内, timer = setTimeout(操作, 时间差)
        • 该函数再次被调用时:
          wait
          
      • 否则,清除首次调用时间,回到第一步。

一个应用场景:监听窗口的 resize 事件响应相关操作。

window.addEventListener(
  'resize',
  throttle(
    () => console.log('窗口大小改变后的操作'),
    1000,
  ),
)

:bulb:
times

源码 | API

调用函数 n 次,将每次的调用结果存进数组并返回。

times(4, () => {
  // 这里将会执行 4 次
})

:bulb:
tryGet

源码 | API

尝试执行 accessor 返回值,若其报错,返回默认值 defaultValue

const obj = { x: 1 }
tryGet(() => obj.x, 2) // => 1
tryGet(() => obj.x.y, 2) // => 2

尝试执行 accessor 返回值,若其报错,返回 undefined

const obj = { x: 1 }
tryGet(() => obj.x) // => 1
tryGet(() => obj.x.y) // => undefined

:bulb:
unique

源码 | API

将给定的数组去重后返回。

unique([1, 2, 1, 3]) // => [1, 2, 3]

:bulb:
values

源码 | API

返回 obj 自身可枚举属性值组成的数组。

values({ x: 1, 2: 'y' }) // => [1, 'y'] 或 ['y', 1]

:bulb:
wait

源码 | API

等待一段时间。

wait(1000).then(() => {
  // 等待 1000 毫秒后执行
})

:package:
工具类

:bulb:
Disposer

源码 | API

资源释放器。

const disposer = new Disposer()
const timer = setInterval(
  () => console.log('ok'),
  1000,
)
disposer.add(() => clearInterval(timer))
document.querySelector('#stop').onclick = () => {
  disposer.dispose()
}

:bulb:
EasyStorage

源码 | API

:bulb:
EasyStorageAdapter

源码 | API

:bulb:
EasyStorageAdapterBrowser

源码 | API

:bulb:
EasyStorageAdapterMemory

源码 | API

:bulb:
EasyStorageAdapterWeapp

源码 | API

微信小程序 Storage 适配器。

由于微信小程序的 wx.getStorageSync 方法对于不存在的项目会返回 空字符串 ,导致无法判断项目是否存在,因此,该适配器对存储的内容做了一层封装,以保证相关操作的结果可确定。

:bulb:
EasyStorageDriverBrowserLocalStorage

源码 | API

:bulb:
EasyStorageDriverBrowserSessionStorage

源码 | API

:bulb:
EasyValidator

源码 | API

数据对象验证器。

interface Data {
  name: string,
  phoneNumber: string,
  pass1: string,
  pass2: string,
}
const ev = new EasyValidator([
  {
    key: 'name',
    type: 'chineseName',
    message: '请输入真实姓名',
  },
  {
    key: 'phoneNumber',
    type: 'chineseMobilePhoneNumber',
    message: '请输入正确的手机号码',
  },
  {
    key: 'phoneNumber',
    test: async ({ phoneNumber }, { updateMessage }) => {
      const result = await checkPhoneNumberAsync(phoneNumber)
      if (!result.valid) {
        updateMessage(result.message)
        return false
      }
    },
    message: '请输入正确的手机号码'
  },
  {
    key: 'pass1',
    test: ({ pass1 }) => pass1.length > 6,
    message: '密码应大于6位',
  },
  {
    key: 'pass2',
    test: ({ pass1, pass2 }) => pass2 === pass1,
    message: '两次密码应一致',
  },
])
ev.validate({
  name: '方一一',
  phoneNumber: '18087030070',
  pass1: '1234567',
  pass2: '12345678'
}).then(res => {
  // => { valid: false, unvalidRules: [{ key: 'pass2', test: ({ pass1, pass2 }) => pass2 === pass1, message: '两次密码应一致' }] }
})

:bulb:
EventBus

源码 | API

事件巴士,管理事件的发布与订阅。

const bus = new EventBus void,
  error: (message: string) => void,
}>()
const unbindSuccessListener = bus.on('success', () => {
  console.log('成功啦')
})
const unbindErrorListener = bus.once('error', message => {
  console.error(message)
})
bus.emit('success')
bus.emit('error', '出错啦')
unbindSuccessListener()
bus.off('error')

:bulb:
Wechat

源码 | API

对微信 JSSDK 的封装。

const wechat = new Wechat()
getWechatConfigAsync().then(config => {
  wechat.config(config)
})
wechat.updateShareData({
  title: '分享标题',
  desc: '分享描述',
  link: '分享链接',
  imgUrl: '缩略图地址',
})
wechat.invoke('scanQRCode').then(res => {
  // => API 调用结果
})

:package:
工具类型

:bulb:
AnyFunction

源码 | API

任意函数类型。

:bulb:
AnyObject

源码 | API

任意对象类型。

:bulb:
AsyncOrSync

源码 | API

// before
type X = PromiseLike | string
// after
type X = AsyncOrSync

:bulb:
Brand

源码 | API

名义化类型。

type User = { id: Brand, name: string }
type Post = { id: Brand, title: string }
type UserIdIsNumber = User['id'] extends number ? true: false // => true
type PostIdIsNumber = Post['id'] extends number ? true: false // => true
type PostIdIsNotUserId = Post['id'] extends User['id'] ? false : true // => true

:bulb:
Defined

源码 | API

T 中排除 undefined 类型。

interface User {
  gender?: 'male' | 'female',
}
// before
type UserGender = Exclude
// after
type UserGender = Defined

:bulb:
If

源码 | API

条件类型。

type X = 'x'
// before
type IsX = X extends 'x' ? true : false
// after
type IsX = If

:bulb:
IsNever

源码 | API

检查 T 是否是 never 类型。

type X = never
// before
type XIsNever = [X] extends [never] ? true : false
// after
type XIsNever = IsNever

:bulb:
LiteralUnion

源码 | API

字面量联合类型。

// before: China, American 将得不到类型提示
type Country = 'China' | 'American' | string
// after: China, American 将得到类型提示
type Country = LiteralUnion

:bulb:
Merge

源码 | API

合并两个类型,后一个类型的定义将覆盖前一个类型的定义。

type X = Merge
// => { x: string, y: number, z: string }

:bulb:
Omit

源码 | API

从接口 T 中去除指定的属性。

type X = Omit
// => { y: string }

:bulb:
OneOrMore

源码 | API

// before
type X = number | number[]
// after
type X = OneOrMore

:bulb:
ValueOf

源码 | API

返回接口 T 属性值的类型。

type V = ValueOf
// => number | string | boolean

许可

MIT

:copyright:
Jay Fong