mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 10:54:44 +00:00
chore(packages/stdlib): add ts and js utility types
This commit is contained in:
2
packages/stdlib/src/types/index.ts
Normal file
2
packages/stdlib/src/types/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './js';
|
||||||
|
export * from './ts';
|
||||||
30
packages/stdlib/src/types/js/casts.test.ts
Normal file
30
packages/stdlib/src/types/js/casts.test.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { toString } from './casts';
|
||||||
|
|
||||||
|
describe('casts', () => {
|
||||||
|
describe('toString', () => {
|
||||||
|
it('correct string representation of a value', () => {
|
||||||
|
// Primitives
|
||||||
|
expect(toString(true)).toBe('[object Boolean]');
|
||||||
|
expect(toString(() => {})).toBe('[object Function]');
|
||||||
|
expect(toString(5)).toBe('[object Number]');
|
||||||
|
expect(toString(BigInt(5))).toBe('[object BigInt]');
|
||||||
|
expect(toString('hello')).toBe('[object String]');
|
||||||
|
expect(toString(Symbol('foo'))).toBe('[object Symbol]');
|
||||||
|
|
||||||
|
// Complex
|
||||||
|
expect(toString([])).toBe('[object Array]');
|
||||||
|
expect(toString({})).toBe('[object Object]');
|
||||||
|
expect(toString(undefined)).toBe('[object Undefined]');
|
||||||
|
expect(toString(null)).toBe('[object Null]');
|
||||||
|
expect(toString(/abc/)).toBe('[object RegExp]');
|
||||||
|
expect(toString(new Date())).toBe('[object Date]');
|
||||||
|
expect(toString(new Error())).toBe('[object Error]');
|
||||||
|
expect(toString(new Promise(() => {}))).toBe('[object Promise]');
|
||||||
|
expect(toString(new Map())).toBe('[object Map]');
|
||||||
|
expect(toString(new Set())).toBe('[object Set]');
|
||||||
|
expect(toString(new WeakMap())).toBe('[object WeakMap]');
|
||||||
|
expect(toString(new WeakSet())).toBe('[object WeakSet]');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
7
packages/stdlib/src/types/js/casts.ts
Normal file
7
packages/stdlib/src/types/js/casts.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* To string any value.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const toString = (value: any): string => Object.prototype.toString.call(value);
|
||||||
183
packages/stdlib/src/types/js/complex.test.ts
Normal file
183
packages/stdlib/src/types/js/complex.test.ts
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { isArray, isObject, isRegExp, isDate, isError, isPromise, isMap, isSet, isWeakMap, isWeakSet } from './complex';
|
||||||
|
|
||||||
|
describe('complex', () => {
|
||||||
|
describe('isArray', () => {
|
||||||
|
it('true if the value is an array', () => {
|
||||||
|
expect(isArray([])).toBe(true);
|
||||||
|
expect(isArray([1, 2, 3])).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not an array', () => {
|
||||||
|
expect(isArray('')).toBe(false);
|
||||||
|
expect(isArray(123)).toBe(false);
|
||||||
|
expect(isArray(true)).toBe(false);
|
||||||
|
expect(isArray(null)).toBe(false);
|
||||||
|
expect(isArray(undefined)).toBe(false);
|
||||||
|
expect(isArray({})).toBe(false);
|
||||||
|
expect(isArray(new Map())).toBe(false);
|
||||||
|
expect(isArray(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isObject', () => {
|
||||||
|
it('true if the value is an object', () => {
|
||||||
|
expect(isObject({})).toBe(true);
|
||||||
|
expect(isObject({ key: 'value' })).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not an object', () => {
|
||||||
|
expect(isObject('')).toBe(false);
|
||||||
|
expect(isObject(123)).toBe(false);
|
||||||
|
expect(isObject(true)).toBe(false);
|
||||||
|
expect(isObject(null)).toBe(false);
|
||||||
|
expect(isObject(undefined)).toBe(false);
|
||||||
|
expect(isObject([])).toBe(false);
|
||||||
|
expect(isObject(new Map())).toBe(false);
|
||||||
|
expect(isObject(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isRegExp', () => {
|
||||||
|
it('true if the value is a regexp', () => {
|
||||||
|
expect(isRegExp(/test/)).toBe(true);
|
||||||
|
expect(isRegExp(new RegExp('test'))).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a regexp', () => {
|
||||||
|
expect(isRegExp('')).toBe(false);
|
||||||
|
expect(isRegExp(123)).toBe(false);
|
||||||
|
expect(isRegExp(true)).toBe(false);
|
||||||
|
expect(isRegExp(null)).toBe(false);
|
||||||
|
expect(isRegExp(undefined)).toBe(false);
|
||||||
|
expect(isRegExp([])).toBe(false);
|
||||||
|
expect(isRegExp({})).toBe(false);
|
||||||
|
expect(isRegExp(new Map())).toBe(false);
|
||||||
|
expect(isRegExp(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isDate', () => {
|
||||||
|
it('true if the value is a date', () => {
|
||||||
|
expect(isDate(new Date())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a date', () => {
|
||||||
|
expect(isDate('')).toBe(false);
|
||||||
|
expect(isDate(123)).toBe(false);
|
||||||
|
expect(isDate(true)).toBe(false);
|
||||||
|
expect(isDate(null)).toBe(false);
|
||||||
|
expect(isDate(undefined)).toBe(false);
|
||||||
|
expect(isDate([])).toBe(false);
|
||||||
|
expect(isDate({})).toBe(false);
|
||||||
|
expect(isDate(new Map())).toBe(false);
|
||||||
|
expect(isDate(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isError', () => {
|
||||||
|
it('true if the value is an error', () => {
|
||||||
|
expect(isError(new Error())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not an error', () => {
|
||||||
|
expect(isError('')).toBe(false);
|
||||||
|
expect(isError(123)).toBe(false);
|
||||||
|
expect(isError(true)).toBe(false);
|
||||||
|
expect(isError(null)).toBe(false);
|
||||||
|
expect(isError(undefined)).toBe(false);
|
||||||
|
expect(isError([])).toBe(false);
|
||||||
|
expect(isError({})).toBe(false);
|
||||||
|
expect(isError(new Map())).toBe(false);
|
||||||
|
expect(isError(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isPromise', () => {
|
||||||
|
it('true if the value is a promise', () => {
|
||||||
|
expect(isPromise(new Promise(() => {}))).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a promise', () => {
|
||||||
|
expect(isPromise('')).toBe(false);
|
||||||
|
expect(isPromise(123)).toBe(false);
|
||||||
|
expect(isPromise(true)).toBe(false);
|
||||||
|
expect(isPromise(null)).toBe(false);
|
||||||
|
expect(isPromise(undefined)).toBe(false);
|
||||||
|
expect(isPromise([])).toBe(false);
|
||||||
|
expect(isPromise({})).toBe(false);
|
||||||
|
expect(isPromise(new Map())).toBe(false);
|
||||||
|
expect(isPromise(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isMap', () => {
|
||||||
|
it('true if the value is a map', () => {
|
||||||
|
expect(isMap(new Map())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a map', () => {
|
||||||
|
expect(isMap('')).toBe(false);
|
||||||
|
expect(isMap(123)).toBe(false);
|
||||||
|
expect(isMap(true)).toBe(false);
|
||||||
|
expect(isMap(null)).toBe(false);
|
||||||
|
expect(isMap(undefined)).toBe(false);
|
||||||
|
expect(isMap([])).toBe(false);
|
||||||
|
expect(isMap({})).toBe(false);
|
||||||
|
expect(isMap(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isSet', () => {
|
||||||
|
it('true if the value is a set', () => {
|
||||||
|
expect(isSet(new Set())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a set', () => {
|
||||||
|
expect(isSet('')).toBe(false);
|
||||||
|
expect(isSet(123)).toBe(false);
|
||||||
|
expect(isSet(true)).toBe(false);
|
||||||
|
expect(isSet(null)).toBe(false);
|
||||||
|
expect(isSet(undefined)).toBe(false);
|
||||||
|
expect(isSet([])).toBe(false);
|
||||||
|
expect(isSet({})).toBe(false);
|
||||||
|
expect(isSet(new Map())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isWeakMap', () => {
|
||||||
|
it('true if the value is a weakmap', () => {
|
||||||
|
expect(isWeakMap(new WeakMap())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a weakmap', () => {
|
||||||
|
expect(isWeakMap('')).toBe(false);
|
||||||
|
expect(isWeakMap(123)).toBe(false);
|
||||||
|
expect(isWeakMap(true)).toBe(false);
|
||||||
|
expect(isWeakMap(null)).toBe(false);
|
||||||
|
expect(isWeakMap(undefined)).toBe(false);
|
||||||
|
expect(isWeakMap([])).toBe(false);
|
||||||
|
expect(isWeakMap({})).toBe(false);
|
||||||
|
expect(isWeakMap(new Map())).toBe(false);
|
||||||
|
expect(isWeakMap(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isWeakSet', () => {
|
||||||
|
it('true if the value is a weakset', () => {
|
||||||
|
expect(isWeakSet(new WeakSet())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a weakset', () => {
|
||||||
|
expect(isWeakSet('')).toBe(false);
|
||||||
|
expect(isWeakSet(123)).toBe(false);
|
||||||
|
expect(isWeakSet(true)).toBe(false);
|
||||||
|
expect(isWeakSet(null)).toBe(false);
|
||||||
|
expect(isWeakSet(undefined)).toBe(false);
|
||||||
|
expect(isWeakSet([])).toBe(false);
|
||||||
|
expect(isWeakSet({})).toBe(false);
|
||||||
|
expect(isWeakSet(new Map())).toBe(false);
|
||||||
|
expect(isWeakSet(new Set())).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
81
packages/stdlib/src/types/js/complex.ts
Normal file
81
packages/stdlib/src/types/js/complex.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { toString } from '.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is an array.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is any[]}
|
||||||
|
*/
|
||||||
|
export const isArray = (value: any): value is any[] => Array.isArray(value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is an object.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is object}
|
||||||
|
*/
|
||||||
|
export const isObject = (value: any): value is object => toString(value) === '[object Object]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a regexp.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is RegExp}
|
||||||
|
*/
|
||||||
|
export const isRegExp = (value: any): value is RegExp => toString(value) === '[object RegExp]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a date.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is Date}
|
||||||
|
*/
|
||||||
|
export const isDate = (value: any): value is Date => toString(value) === '[object Date]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is an error.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is Error}
|
||||||
|
*/
|
||||||
|
export const isError = (value: any): value is Error => toString(value) === '[object Error]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a promise.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is Promise<any>}
|
||||||
|
*/
|
||||||
|
export const isPromise = (value: any): value is Promise<any> => toString(value) === '[object Promise]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a map.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is Map<any, any>}
|
||||||
|
*/
|
||||||
|
export const isMap = (value: any): value is Map<any, any> => toString(value) === '[object Map]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a set.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is Set<any>}
|
||||||
|
*/
|
||||||
|
export const isSet = (value: any): value is Set<any> => toString(value) === '[object Set]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a weakmap.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is WeakMap<object, any>}
|
||||||
|
*/
|
||||||
|
export const isWeakMap = (value: any): value is WeakMap<object, any> => toString(value) === '[object WeakMap]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a weakset.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is WeakSet<object>}
|
||||||
|
*/
|
||||||
|
export const isWeakSet = (value: any): value is WeakSet<object> => toString(value) === '[object WeakSet]';
|
||||||
3
packages/stdlib/src/types/js/index.ts
Normal file
3
packages/stdlib/src/types/js/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './casts';
|
||||||
|
export * from './primitives';
|
||||||
|
export * from './complex';
|
||||||
101
packages/stdlib/src/types/js/primitives.test.ts
Normal file
101
packages/stdlib/src/types/js/primitives.test.ts
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { isBoolean, isFunction, isNumber, isBigInt, isString, isSymbol, isUndefined, isNull } from './primitives';
|
||||||
|
|
||||||
|
describe('primitives', () => {
|
||||||
|
describe('isBoolean', () => {
|
||||||
|
it('true if the value is a boolean', () => {
|
||||||
|
expect(isBoolean(true)).toBe(true);
|
||||||
|
expect(isBoolean(false)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a boolean', () => {
|
||||||
|
expect(isBoolean(0)).toBe(false);
|
||||||
|
expect(isBoolean('true')).toBe(false);
|
||||||
|
expect(isBoolean(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isFunction', () => {
|
||||||
|
it('true if the value is a function', () => {
|
||||||
|
expect(isFunction(() => {})).toBe(true);
|
||||||
|
expect(isFunction(function() {})).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a function', () => {
|
||||||
|
expect(isFunction(123)).toBe(false);
|
||||||
|
expect(isFunction('function')).toBe(false);
|
||||||
|
expect(isFunction(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isNumber', () => {
|
||||||
|
it('true if the value is a number', () => {
|
||||||
|
expect(isNumber(123)).toBe(true);
|
||||||
|
expect(isNumber(3.14)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a number', () => {
|
||||||
|
expect(isNumber('123')).toBe(false);
|
||||||
|
expect(isNumber(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isBigInt', () => {
|
||||||
|
it('true if the value is a bigint', () => {
|
||||||
|
expect(isBigInt(BigInt(123))).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a bigint', () => {
|
||||||
|
expect(isBigInt(123)).toBe(false);
|
||||||
|
expect(isBigInt('123')).toBe(false);
|
||||||
|
expect(isBigInt(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isString', () => {
|
||||||
|
it('true if the value is a string', () => {
|
||||||
|
expect(isString('hello')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a string', () => {
|
||||||
|
expect(isString(123)).toBe(false);
|
||||||
|
expect(isString(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isSymbol', () => {
|
||||||
|
it('true if the value is a symbol', () => {
|
||||||
|
expect(isSymbol(Symbol())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not a symbol', () => {
|
||||||
|
expect(isSymbol(123)).toBe(false);
|
||||||
|
expect(isSymbol('symbol')).toBe(false);
|
||||||
|
expect(isSymbol(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isUndefined', () => {
|
||||||
|
it('true if the value is undefined', () => {
|
||||||
|
expect(isUndefined(undefined)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not undefined', () => {
|
||||||
|
expect(isUndefined(null)).toBe(false);
|
||||||
|
expect(isUndefined(123)).toBe(false);
|
||||||
|
expect(isUndefined('undefined')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isNull', () => {
|
||||||
|
it('true if the value is null', () => {
|
||||||
|
expect(isNull(null)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false if the value is not null', () => {
|
||||||
|
expect(isNull(undefined)).toBe(false);
|
||||||
|
expect(isNull(123)).toBe(false);
|
||||||
|
expect(isNull('null')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
65
packages/stdlib/src/types/js/primitives.ts
Normal file
65
packages/stdlib/src/types/js/primitives.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { toString } from '.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a boolean.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is boolean}
|
||||||
|
*/
|
||||||
|
export const isBoolean = (value: any): value is boolean => typeof value === 'boolean';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a function.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is Function}
|
||||||
|
*/
|
||||||
|
export const isFunction = <T extends Function>(value: any): value is T => typeof value === 'function';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a number.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is number}
|
||||||
|
*/
|
||||||
|
export const isNumber = (value: any): value is number => typeof value === 'number';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a bigint.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is bigint}
|
||||||
|
*/
|
||||||
|
export const isBigInt = (value: any): value is bigint => typeof value === 'bigint';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a string.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is string}
|
||||||
|
*/
|
||||||
|
export const isString = (value: any): value is string => typeof value === 'string';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a symbol.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is symbol}
|
||||||
|
*/
|
||||||
|
export const isSymbol = (value: any): value is symbol => typeof value === 'symbol';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a undefined.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is undefined}
|
||||||
|
*/
|
||||||
|
export const isUndefined = (value: any): value is undefined => toString(value) === '[object Undefined]';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a null.
|
||||||
|
*
|
||||||
|
* @param {any} value
|
||||||
|
* @returns {value is null}
|
||||||
|
*/
|
||||||
|
export const isNull = (value: any): value is null => toString(value) === '[object Null]';
|
||||||
1
packages/stdlib/src/types/ts/index.ts
Normal file
1
packages/stdlib/src/types/ts/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './string';
|
||||||
43
packages/stdlib/src/types/ts/string.test-d.ts
Normal file
43
packages/stdlib/src/types/ts/string.test-d.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { describe, expectTypeOf, it } from 'vitest';
|
||||||
|
import type { HasSpaces, Trim } from './string';
|
||||||
|
|
||||||
|
describe('string', () => {
|
||||||
|
describe('Trim', () => {
|
||||||
|
it('remove leading and trailing spaces from a string', () => {
|
||||||
|
type actual = Trim<' hello '>;
|
||||||
|
type expected = 'hello';
|
||||||
|
|
||||||
|
expectTypeOf<actual>().toEqualTypeOf<expected>();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove only leading spaces from a string', () => {
|
||||||
|
type actual = Trim<' hello'>;
|
||||||
|
type expected = 'hello';
|
||||||
|
|
||||||
|
expectTypeOf<actual>().toEqualTypeOf<expected>();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove only trailing spaces from a string', () => {
|
||||||
|
type actual = Trim<'hello '>;
|
||||||
|
type expected = 'hello';
|
||||||
|
|
||||||
|
expectTypeOf<actual>().toEqualTypeOf<expected>();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HasSpaces', () => {
|
||||||
|
it('check if a string has spaces', () => {
|
||||||
|
type actual = HasSpaces<'hello world'>;
|
||||||
|
type expected = true;
|
||||||
|
|
||||||
|
expectTypeOf<actual>().toEqualTypeOf<expected>();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('check if a string has no spaces', () => {
|
||||||
|
type actual = HasSpaces<'helloworld'>;
|
||||||
|
type expected = false;
|
||||||
|
|
||||||
|
expectTypeOf<actual>().toEqualTypeOf<expected>();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
9
packages/stdlib/src/types/ts/string.ts
Normal file
9
packages/stdlib/src/types/ts/string.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Trim leading and trailing whitespace from `S`
|
||||||
|
*/
|
||||||
|
export type Trim<S extends string> = S extends ` ${infer R}` ? Trim<R> : S extends `${infer L} ` ? Trim<L> : S;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if `S` has any spaces
|
||||||
|
*/
|
||||||
|
export type HasSpaces<S extends string> = S extends `${string} ${string}` ? true : false;
|
||||||
Reference in New Issue
Block a user