# utils **Repository Path**: ModyQyW/utils ## Basic Information - **Project Name**: utils - **Description**: 不同 JavaScript/TypeScript 项目的可共享工具方法。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-06-01 - **Last Updated**: 2023-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # @modyqyw/utils [![License](https://img.shields.io/github/license/ModyQyW/utils)](https://github.com/ModyQyW/utils/blob/main/LICENSE) [![npm](https://img.shields.io/npm/v/@modyqyw/utils)](https://www.npmjs.com/package/@modyqyw/utils/) English | [简体中文](./README.zh-Hans.md) Opinionated shareable utils for different JavaScript/TypeScript projects. Requires `node >= 14.18`. ## Installation ```shell npm install @modyqyw/utils ``` ## API ### base - Try [deepmerge](https://github.com/TehShrike/deepmerge), [deepmerge-ts](https://github.com/RebeccaStevens/deepmerge-ts) or [ts-deepmerge](https://github.com/voodoocreation/ts-deepmerge) if you are looking for a merge solution. - Try [deepmerge](https://github.com/TehShrike/deepmerge), [deepmerge-ts](https://github.com/RebeccaStevens/deepmerge-ts), [ts-deepmerge](https://github.com/voodoocreation/ts-deepmerge), [clone](https://github.com/pvorb/clone) or [structuredClone](https://developer.mozilla.org/docs/Web/API/structuredClone) if you are looking for a clone solution. ### getType Get value type name. ```typescript import { getType } from '@modyqyw/utils'; getType(null); // Null getType(); // Undefined getType(undefined); // Undefined getType(true); // Boolean getType(0); // Number getType(0n); // BigInt getType(''); // String getType({}); // Object getType([]); // Array ``` #### isString Determine if a value is a string. ```typescript import { isString } from '@modyqyw/utils'; isString(''); // true isString(0); // false isString(0n); // false isString(true); // false isString(undefined); // false isString(null); // false isString(Symbol()); // false isString({}); // false isString(() => {}); // false isString([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isNumber Determine if a value is a number. ```typescript import { isNumber } from '@modyqyw/utils'; isNumber(''); // false isNumber(0); // true isNumber(0n); // false isNumber(true); // false isNumber(undefined); // false isNumber(null); // false isNumber(Symbol()); // false isNumber({}); // false isNumber(() => {}); // false isNumber([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isBigInt Determine if a value is a bigint. ```typescript import { isBigInt } from '@modyqyw/utils'; isBigInt(''); // false isBigInt(0); // false isBigInt(0n); // true isBigInt(true); // false isBigInt(undefined); // false isBigInt(null); // false isBigInt(Symbol()); // false isBigInt({}); // false isBigInt(() => {}); // false isBigInt([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isBoolean Determine if a value is a boolean. ```typescript import { isBoolean } from '@modyqyw/utils'; isBoolean(''); // false isBoolean(0); // false isBoolean(0n); // false isBoolean(true); // true isBoolean(undefined); // false isBoolean(null); // false isBoolean(Symbol()); // false isBoolean({}); // false isBoolean(() => {}); // false isBoolean([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isUndefined Determine if a value is undefined. ```typescript import { isUndefined } from '@modyqyw/utils'; isUndefined(''); // false isUndefined(0); // false isUndefined(0n); // false isUndefined(true); // false isUndefined(undefined); // true isUndefined(null); // false isUndefined(Symbol()); // false isUndefined({}); // false isUndefined(() => {}); // false isUndefined([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isNull Determine if a value is null. ```typescript import { isNull } from '@modyqyw/utils'; isNull(''); // false isNull(0); // false isNull(0n); // false isNull(true); // false isNull(undefined); // false isNull(null); // true isNull(Symbol()); // false isNull({}); // false isNull(() => {}); // false isNull([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isNullish Determine if a value is null or undefined. ```typescript import { isNullish } from '@modyqyw/utils'; isNullish(''); // false isNullish(0); // false isNullish(0n); // false isNullish(true); // false isNullish(undefined); // true isNullish(null); // true isNullish(Symbol()); // false isNullish({}); // false isNullish(() => {}); // false isNullish([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isSymbol Determine if a value is a symbol. ```typescript import { isSymbol } from '@modyqyw/utils'; isSymbol(''); // false isSymbol(0); // false isSymbol(0n); // false isSymbol(true); // false isSymbol(undefined); // false isSymbol(null); // false isSymbol(Symbol()); // true isSymbol({}); // false isSymbol(() => {}); // false isSymbol([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isObject Determine if a value is a object. ```typescript import { isObject } from '@modyqyw/utils'; isObject(''); // false isObject(0); // false isObject(0n); // false isObject(true); // false isObject(undefined); // false isObject(null); // false isObject(Symbol()); // false isObject({}); // true isObject(() => {}); // false isObject([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isFunction Determine if a value is a function. ```typescript import { isFunction } from '@modyqyw/utils'; isFunction(''); // false isFunction(0); // false isFunction(0n); // false isFunction(true); // false isFunction(undefined); // false isFunction(null); // false isFunction(Symbol()); // false isFunction({}); // false isFunction(() => {}); // true isFunction([]); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isArray Determine if a value is an array. ```typescript import { isArray } from '@modyqyw/utils'; isArray(''); // false isArray(0); // false isArray(0n); // false isArray(true); // false isArray(undefined); // false isArray(null); // false isArray(Symbol()); // false isArray({}); // false isArray(() => {}); // false isArray([]); // true ``` You may want to determine if a value is an array and all of its items are numbers. Here is an example. ```typescript import { isArray, isNumber } from '@modyqyw/utils'; isArray([1, 2, 3], isNumber); // true isArray([1, 2, '3'], isNumber); // false ``` You can check [@sindresorhus/is](https://github.com/sindresorhus/is) for extra needs, such as `is.xxx` and type assertions. #### isBlob Determine if a value is a blob. #### isFile Determine if a value is a file. #### getTimestamp Get millisecond-based timestamp. ```typescript import { getTimestamp } from '@modyqyw/utils'; const timestamp = getTimestamp(); ``` #### isEqual Use `Object.is` directly to determine if two values are equal. Use [isDeepEqual](#isdeepequal) if you need a deep comparison. ```typescript import { isEqual } from '@modyqyw/utils'; isEqual(null, null); // true isEqual(undefined, null); // false isEqual(undefined, undefined); // true isEqual(true, true); // true isEqual(false, false); // true isEqual(true, false); // true isEqual(1, 2); // false isEqual(1, 1); // true isEqual({}, {}); // false isEqual({ a: 1 }, { a: 1, b: 2 }); // false isEqual({ a: 1 }, { a: 1 }); // false isEqual({ a: 1, b: { c: true } }, { a: 1, b: { c: true } }); // false isEqual({ a: 1, b: { c: true } }, { a: 1, b: { c: false } }); // false isEqual([], []); // false isEqual([1, 2, 3, { a: 1, b: { c: true } }], [1, 2, 3, { a: 1, b: { c: true } }]); // false isEqual([1, 2, 3, { a: 1, b: { c: true } }], [1, 2, 3, { a: 1, b: { c: false } }]); // false ``` #### isDeepEqual Determine if two values are equal. For arrays, recursively determine the value corresponding to each index. For objects, recursively determine the value of each key. Other cases are determined with `Object.is`. ```typescript import { isDeepEqual } from '@modyqyw/utils'; isDeepEqual(null, null); // true isDeepEqual(undefined, null); // false isDeepEqual(undefined, undefined); // true isDeepEqual(true, true); // true isDeepEqual(false, false); // true isDeepEqual(true, false); // true isDeepEqual(1, 2); // false isDeepEqual(1, 1); // true isDeepEqual({}, {}); // true isDeepEqual({ a: 1 }, { a: 1, b: 2 }); // false isDeepEqual({ a: 1 }, { a: 1 }); // true isDeepEqual({ a: 1, b: { c: true } }, { a: 1, b: { c: true } }); // true isDeepEqual({ a: 1, b: { c: true } }, { a: 1, b: { c: false } }); // false isDeepEqual([], []); // true isDeepEqual([1, 2, 3, { a: 1, b: { c: true } }], [1, 2, 3, { a: 1, b: { c: true } }]); // true isDeepEqual([1, 2, 3, { a: 1, b: { c: true } }], [1, 2, 3, { a: 1, b: { c: false } }]); // false ``` ### string #### lowerCase Convert string to lower case. ```typescript import { lowerCase } from '@modyqyw/utils'; lowerCase(''); // '' lowerCase('test'); // 'test' lowerCase('TEST'); // 'test' lowerCase('test string'); // 'test string' lowerCase('TEST STRING'); // 'test string' ``` #### localeLowerCase Convert string to locale lower case. ```typescript import { localeLowerCase } from '@modyqyw/utils'; localeLowerCase('STRING', 'en-US'); // 'string' ``` #### lowerCaseFirst Convert first char to lower case. ```typescript import { lowerCaseFirst } from '@modyqyw/utils'; lowerCaseFirst(''); // '' lowerCaseFirst('test'); // 'test' lowerCaseFirst('TEST'); // 'tEST' lowerCaseFirst('test string'); // 'test string' lowerCaseFirst('TEST STRING'); // 'tEST STRING' ``` #### upperCase Convert string to upper case. ```typescript import { upperCase } from '@modyqyw/utils'; upperCase(''); // '' upperCase('test'); // 'TEST' upperCase('TEST'); // 'TEST' upperCase('test string'); // 'TEST STRING' upperCase('TEST STRING'); // 'TEST STRING' ``` #### localeUpperCase Convert string to locale upper case. ```typescript import { localeLowerCase } from '@modyqyw/utils'; localeLowerCase('string', 'en-US'); // 'STRING' ``` #### upperCaseFirst Convert first char to upper case. ```typescript import { lowerCaseFirst } from '@modyqyw/utils'; lowerCaseFirst(''); // '' lowerCaseFirst('test'); // 'test' lowerCaseFirst('TEST'); // 'tEST' lowerCaseFirst('test string'); // 'test string' lowerCaseFirst('TEST STRING'); // 'tEST STRING' ``` #### toString Convert value to string. Try `value.toString()` first, then `Object#toString.call(value)`. ```typescript import { toString } from '@modyqyw/utils'; toString(undefined); // '[object Undefined]' toString(null); // '[object Null]' toString(0); // '0' toString(Symbol('test')); // 'Symbol(test)' toString([1, 2, 3]); // '1,2,3' ``` ### array #### arrayIncludes Same as `Array#includes`. With better types. From [ts-extras](https://github.com/sindresorhus/ts-extras). #### toArray Convert value to an array. ```typescript import { toArray } from '@modyqyw/utils'; toArray(); // [] toArray(undefined); // [] toArray(null); // [] toArray(1); // [1] toArray('abc'); // ['abc'] toArray({ a: 1, b: 2 }); // [{ a: 1, b: 2 }] toArray([1, 2]); // [1, 2] ``` #### difference Find difference elements between two arrays. Pass a function to judge equation or fallback to `Array#includes`. Return a new array. ```typescript import { difference, isDeepEqual } from '@modyqyw/utils'; difference([1, '2'], [1]); // ['2'] difference([1, '2', {}], [1, {}]); // ['2', {}] difference([1, '2', { a: { b: 'c' } }], [1, { a: { b: 'c' } }]); // ['2', { a: { b: 'c' } }] difference([1, '2', {}], [1, {}], isDeepEqual); // ['2'] difference([1, '2', { a: { b: 'c' } }], [1, { a: { b: 'c' } }], isDeepEqual); // ['2'] ``` #### intersection Find same elements between two arrays. Pass a function to judge equation or fallback to `Array#includes`. Return a new array. ```typescript import { intersection, isDeepEqual } from '@modyqyw/utils'; intersection([1, '2'], [1]); // [1] intersection([1, '2', {}], [1, {}]); // [1] intersection([1, '2', { a: { b: 'c' } }], [1, { a: { b: 'c' } }]); // [1] intersection([1, '2', {}], [1, {}], isDeepEqual); // [1, {}] intersection([1, '2', { a: { b: 'c' } }], [1, { a: { b: 'c' } }], isDeepEqual); // [1, { a: { b: 'c' } }] ``` #### uniq Find unique elements. Pass a function to judge equation or fallback to `Set`. Return a new array. ```typescript import { uniq, isDeepEqual } from '@modyqyw/utils'; uniq([1, '2', 2, 2, '2']); // [1, '2', 2] uniq([1, '2', 2, 2, '2', {}, {}]); // [1, '2', 2, {}, {}] uniq([1, '2', 2, 2, '2', {}, {}], isDeepEqual); // [1, '2', 2, {}] ``` #### union Find all different elements in two arrays. Use `uniq` under the hood. Return a new array. ```typescript import { union, isDeepEqual } from '@modyqyw/utils'; union([1, '2'], [1, 3]); // [1, '2', 3] union([1, '2', {}], [1, 3, {}]); // [1, '2', {}, 3, {}] union([1, '2', { a: { b: 'c' } }], [1, 3, { a: { b: 'c' } }]); // [1, '2', { a: { b: 'c' } }, 3, { a: { b: 'c' } }]) union([1, '2', {}], [1, 3, {}], isDeepEqual); // [1, '2', {}, 3] union([1, '2', { a: { b: 'c' } }], [1, 3, { a: { b: 'c' } }], isDeepEqual); // [1, '2', { a: { b: 'c' } }, 3] ``` #### range Creates an array of numbers (positive and/or negative) progressing from `start` up to, but not including `end`. `start` is set to 0 by default. You can pass `end` directly. `step` is set to 1 when `start` < `end` and -1 when `start` >= `end` by default. Return a new array. ```typescript import { range } from '@modyqyw/utils'; range(4); // [0, 1, 2, 3] range(-4); // [0, -1, -2, -3] range(1, 5); // [1, 2, 3, 4] range(0, 20, 5); // [0, 5, 10, 15] range(0, -4, -1); // [0, -1, -2, -3] range(1, 4, 0); // [1, 1, 1] range(0); // [] ``` ### object #### objectKeys Same as `Object.keys`. With better types. From [ts-extras](https://github.com/sindresorhus/ts-extras). #### objectEntries Same as `Object.entries`. With better types. From [ts-extras](https://github.com/sindresorhus/ts-extras). #### objectFromEntries Same as `Object.fromEntries`. With better types. From [ts-extras](https://github.com/sindresorhus/ts-extras). ### set #### setHas Same as `Set#has`. With better types. From [ts-extras](https://github.com/sindresorhus/ts-extras). ### promise You can check [promise-fun](https://github.com/sindresorhus/promise-fun) for extra needs. #### sleep Sleep 💤, then call `callback` if passed. ```typescript import { sleep } from '@modyqyw/utils'; await sleep(1000); // sleep 1s await sleep(1000, () => { console.log('Hi.'); }); // sleep 1s, then log `Hi.` ``` ### function #### throttle Creates a throttled function that only invokes `callback` at most once per every `delay` milliseconds. ```typescript import { throttle } from '@modyqyw/utils'; const throttled = throttle(fn, 1000); throttled(); // called throttled(); throttled(); throttled(); // called setTimeout(throttled, 1200); // called ``` You can disable `leading` or `trailing` in the third param. Default `{ leading: true, trailing: true }`. ```typescript import { throttle } from '@modyqyw/utils'; const throttled = throttle(fn, 1000, { trailing: false }); throttled(); // called throttled(); throttled(); throttled(); setTimeout(throttled, 1200); // called ``` ```typescript import { throttle } from '@modyqyw/utils'; const throttled = throttle(fn, 1000, { leading: false }); throttled(); throttled(); throttled(); throttled(); // called setTimeout(throttled, 1200); // called ``` ```typescript import { throttle } from '@modyqyw/utils'; const throttled = throttle(fn, 1000, { leading: false, trailing: false }); throttled(); throttled(); throttled(); throttled(); setTimeout(throttled, 1200); ``` Use `.abort()` to abort next invocations. Pass `true` to abort the next invocation. ```typescript import { throttle } from '@modyqyw/utils'; const throttled = throttle(fn, 1000); throttled(); // called throttled(); throttled.abort(true); throttled(); // called throttled.abort(); throttled(); throttled(); ``` See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) for details over the differences between throttle and debounce. #### debounce Creates a debounced function that delays invoking `callback` until after `delay` milliseconds have elapsed since the last time the debounced function was invoked. ```typescript import { debounce } from '@modyqyw/utils'; const debounced = debounce(fn, 1000); debounced(); debounced(); debounced(); debounced(); // called setTimeout(debounced, 1200); // called ``` You can disable `leading` or `trailing` in the third param. Default `{ leading: false, trailing: true }`. ```typescript import { debounce } from '@modyqyw/utils'; const debounced = debounce(fn, 1000, { leading: false, trailing: false }); debounced(); debounced(); debounced(); debounced(); setTimeout(debounced, 1200); ``` ```typescript import { debounce } from '@modyqyw/utils'; const debounced = debounce(fn, 1000, { leading: true, trailing: true }); debounced(); // called debounced(); debounced(); debounced(); // called setTimeout(debounced, 1200); // called ``` ```typescript import { debounce } from '@modyqyw/utils'; const debounced = debounce(fn, 1000, { leading: true, trailing: false }); debounced(); // called debounced(); debounced(); debounced(); setTimeout(debounced, 1200); // called ``` Use `.abort()` to abort next invocations. Pass `true` to abort the next invocation. ```typescript import { debounce } from '@modyqyw/utils'; const debounced = debounce(fn, 1000); debounced(); debounced(); debounced.abort(true); debounced(); // called debounced.abort(); debounced(); debounced(); ``` #### pipe Performs left-to-right function composition. ```typescript import { pipe } from '@modyqyw/utils'; const fn = pipe( (a: number, b: number) => a + b, // first do (a) => Math.pow(a, 2), // second do (a) => a * 3, (a) => a / 4, (a) => a - 2, ); fn(1, 1); // 1 ``` #### noop Empty function. ```typescript import { noop } from '@modyqyw/utils'; // nothing happen noop(); ``` ### types You can check [type-fest](https://github.com/sindresorhus/type-fest), [ts-toolbelt](https://github.com/millsp/ts-toolbelt) and [ts-essentials](https://github.com/ts-essentials/ts-essentials) for extra needs. #### AnyRecord ```typescript type AnyRecord = Record; ``` #### Falsy ```typescript type Falsy = false | 0 | 0n | '' | null | undefined; ``` #### MaybePromise ```typescript type MaybePromise = T | Promise; ``` #### MaybePromiseLike ```typescript type MaybePromiseLike = T | PromiseLike; ``` #### Promisable ```typescript type Promisable = T | PromiseLike; ``` #### Awaitable ```typescript type Awaitable = T | PromiseLike; ``` #### MaybeNull ```typescript type MaybeNull = T | null; ``` #### Nullable ```typescript type Nullable = T | null; ``` #### NonNullable **This is not the same as TypeScript [NonNullable](https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype).** ```typescript type NonNullable = Exclude; ``` #### MaybeUndefined ```typescript type MaybeUndefined = T | undefined; ``` #### Optional ```typescript type Optional = T | undefined; ``` #### Undefinable ```typescript type Undefinable = Optional; ``` #### Nullish ```typescript type Nullish = T | undefined | null; ``` #### NonNullish **This is the same as TypeScript [NonNullable](https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype).** ```typescript type NonNullish = Exclude; ``` #### MaybeArray ```typescript type MaybeArray = T | Array; ``` #### Arrayable ```typescript type Arrayable = T | Array; ``` #### ElementOf ```typescript type ElementOf = T extends (infer E)[] ? E : never; ``` #### Fn ```typescript type Fn = () => void; ``` #### PromisifyFn ```typescript type PromisifyFn = () => Promise>; ``` #### AnyFn ```typescript type AnyFn = (...args: any[]) => T; ``` #### PromisifyAnyFn ```typescript type PromisifyAnyFn = (...args: Parameters) => Promise>; ``` ## Acknowledges Inspired by [@antfu/utils](https://github.com/antfu/utils). I have checked and learned from these libraries. Thanks a lot! Check them for more if you need. - [lodash](https://lodash.com/) - [ramda](https://ramdajs.com/) - [remeda](https://remedajs.com/) - [fp-ts](https://gcanti.github.io/fp-ts/) - [io-ts](https://gcanti.github.io/io-ts/) - [change-case](https://github.com/blakeembrey/change-case) - [promise-fun](https://github.com/sindresorhus/promise-fun) - [rxjs](https://rxjs.dev/) - [mlly](https://github.com/unjs/mlly) - [pkg-types](https://github.com/unjs/pkg-types) - [local-pkg](https://github.com/antfu/local-pkg) - [type-fest](https://github.com/sindresorhus/type-fest) - [ts-essentials](https://github.com/ts-essentials/ts-essentials) - [ts-toolbelt](https://github.com/millsp/ts-toolbelt) - [throttle-debounce](https://github.com/niksy/throttle-debounce) - [js-sdsl](https://js-sdsl.org/) - [joi](https://joi.dev/) - [zod](https://zod.dev/) - [yup](https://github.com/jquense/yup) ## [Sponsors](https://github.com/ModyQyW/sponsors)