@bedard/utils
v0.33.1
Published
[![Build status](https://img.shields.io/github/actions/workflow/status/scottbedard/utils/test.yml?branch=main)](https://github.com/scottbedard/utils/actions) [![Codecov](https://img.shields.io/codecov/c/github/scottbedard/utils)](https://codecov.io/gh/sco
Downloads
222
Readme
@bedard/utils
This repository acts as my own personal lodash. It contains a number of utility types and functions that I found myself duplicating between projects. I do not anticipate breaking changes, but I'm also not ruling it out. Upgrade with caution.
Installation
The recommended installation method is via NPM.
npm install @bedard/utils
Alternatively, the functions maybe be accessed via a CDN. When using the CDN, the library will be exposed globally as BedardUtils
.
<script src="https://unpkg.com/@bedard/utils"></script>
Functions
Animation
createEasingFunction
easeInSine
easeOutSine
easeInOutSine
easeInQuad
easeOutQuad
easeInOutQuad
easeInCubic
easeOutCubic
easeInOutCubic
easeInQuart
easeOutQuart
easeInOutQuart
easeInQuint
easeOutQuint
easeInOutQuint
easeInExpo
easeOutExpo
easeInOutExpo
easeInCirc
easeOutCirc
easeInOutCirc
easeInBack
easeOutBack
easeInOutBack
easeInElastic
easeOutElastic
easeInOutElastic
easeInBounce
easeOutBounce
easeInOutBounce
Color
Math
addVectors
angleFrom
bilerp
cols
degreesToRadians
flattenCols
flattenRows
flip
intersect
isEven
lerp
lerpVectors
measure
polygon
radiansToDegrees
roll
rotateMatrix
rotateVector
rows
scale
slope
Utility
addVectors
Add vectors together.
import { addVectors } from '@bedard/utils'
addVectors([1, 2], [3, 4]) // [4, 6]
angleFrom
Calculate angled distance from a vector. An angle of 0
degrees will track along the X axis, with positive angles rotating counter-clockwise.
import { angleFrom } from '@bedard/utils'
angleFrom([0, 0], 90, 1) // [0, 1] (approximate)
bilerp
Bi-linear interpolation between vectors.
import { bilerp } from '@bedard/utils'
bilerp([0, 0], [10, 10], 0.5) // [5, 5]
cols
Chunk a square matrix into columns. Note that the source matrix must be provided in row-major order.
import { cols } from '@bedard/utils'
cols([
0, 1, 2,
3, 4, 5,
6, 7, 8,
]) // [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
createEasingFunction
Create an easing function from cubic-bezier points. Note that the included easing functions do not use this utility. They are simpler mathematical functions, and do not produce quite the same results as easing functions created using this utility.
import { createEasingFunction } from '@bedard/utils'
const linear = createEasingFunction(0, 0, 1, 1)
linear(0.5) // 0.5
deepEqual
Deep object comparison.
import { deepEqual } from '@bedard/utils'
deepEqual({ foo: { bar: 1 }}, { foo: { bar: 1 }}) // true
degreesToRadians
Convert degrees to radians.
import { degreesToRadians } from '@bedard/utils'
degreesToRadians(180) // 3.141592653589793
easeInSine
Easing function that follows this curve.
import { easeInSine } from '@bedard/utils'
easeInSine(0.5) // 0.2928932188134524
easeOutSine
Easing function that follows this curve.
import { easeOutSine } from '@bedard/utils'
easeOutSine(0.5) // 0.7071067811865475
easeInOutSine
Easing function that follows this curve.
import { easeInOutSine } from '@bedard/utils'
easeInOutSine(0.5) // 0.49999999999999994
easeInQuad
Easing function that follows this curve.
import { easeInQuad } from '@bedard/utils'
easeInQuad(0.5) // 0.25
easeOutQuad
Easing function that follows this curve.
import { easeOutQuad } from '@bedard/utils'
easeOutQuad(0.5) // 0.75
easeInOutQuad
Easing function that follows this curve.
import { easeInOutQuad } from '@bedard/utils'
easeInOutQuad(0.5) // 0.5
easeInCubic
Easing function that follows this curve.
import { easeInCubic } from '@bedard/utils'
easeInCubic(0.5) // 0.125
easeOutCubic
Easing function that follows this curve.
import { easeOutCubic } from '@bedard/utils'
easeOutCubic(0.5) // 0.875
easeInOutCubic
Easing function that follows this curve.
import { easeInOutCubic } from '@bedard/utils'
easeInOutCubic(0.5) // 0.5
easeInQuart
Easing function that follows this curve.
import { easeInQuart } from '@bedard/utils'
easeInQuart(0.5) // 0.0625
easeOutQuart
Easing function that follows this curve.
import { easeOutQuart } from '@bedard/utils'
easeOutQuart(0.5) // 0.9375
easeInOutQuart
Easing function that follows this curve.
import { easeInOutQuart } from '@bedard/utils'
easeInOutQuart(0.5) // 0.5
easeInQuint
Easing function that follows this curve.
import { easeInQuint } from '@bedard/utils'
easeInQuint(0.5) // 0.03125
easeOutQuint
Easing function that follows this curve.
import { easeOutQuint } from '@bedard/utils'
easeOutQuint(0.5) // 0.96875
easeInOutQuint
Easing function that follows this curve.
import { easeInOutQuint } from '@bedard/utils'
easeInOutQuint(0.5) // 0.5
easeInExpo
Easing function that follows this curve.
import { easeInExpo } from '@bedard/utils'
easeInExpo(0.5) // 0.03125
easeOutExpo
Easing function that follows this curve.
import { easeOutExpo } from '@bedard/utils'
easeOutExpo(0.5) // 0.96875
easeInOutExpo
Easing function that follows this curve.
import { easeInOutExpo } from '@bedard/utils'
easeInOutExpo(0.5) // 0.5
easeInCirc
Easing function that follows this curve.
import { easeInCirc } from '@bedard/utils'
easeInCirc(0.5) // 0.1339745962155614
easeOutCirc
Easing function that follows this curve.
import { easeOutCirc } from '@bedard/utils'
easeOutCirc(0.5) // 0.8660254037844386
easeInOutCirc
Easing function that follows this curve.
import { easeInOutCirc } from '@bedard/utils'
easeInOutCirc(0.5) // 0.5
easeInBack
Easing function that follows this curve.
import { easeInBack } from '@bedard/utils'
easeInBack(0.5) // -0.08769750000000004
easeOutBack
Easing function that follows this curve.
import { easeOutBack } from '@bedard/utils'
easeOutBack(0.5) // 1.0876975
easeInOutBack
Easing function that follows this curve.
import { easeInOutBack } from '@bedard/utils'
easeInOutBack(0.5) // 0.5
easeInElastic
Easing function that creates an elastic-in effect.
import { easeInElastic } from '@bedard/utils'
easeInElastic(0.5) // -0.015625000000000045
easeOutElastic
Easing function that creates an elastic-out effect.
import { easeOutElastic } from '@bedard/utils'
easeOutElastic(0.5) // 1.015625
easeInOutElastic
Easing function that creates an elastic-in-out effect.
import { easeInOutElastic } from '@bedard/utils'
easeInOutElastic(0.5) // 0.5
easeInBounce
Easing function that creates a bounce-in effect.
import { easeInBounce } from '@bedard/utils'
easeInBounce(0.5) // 0.234375
easeOutBounce
Easing function that creates a bounce-out effect.
import { easeOutBounce } from '@bedard/utils'
easeOutBounce(0.5) // 0.765625
easeInOutBounce
Easing function that creates a bounce-in-out effect.
import { easeInOutBounce } from '@bedard/utils'
easeInOutBounce(0.5) // 0.5
entries
Type safe wrapper around Object.entries
import { entries } from '@bedard/utils'
entries({ foo: 'bar' }) // [['foo', 'bar']]
flattenCols
Flatten an array of columns to a matrix in row-major order.
import { flattenCols } from '@bedard/utils'
flattenCols([
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
]) // [0, 1, 2, 3, 4, 5, 6, 7, 8]
flattenRows
Flatten an array of rows to a matrix in row-major order.
import { flattenRows } from '@bedard/utils'
flattenRows([
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
]) // [0, 1, 2, 3, 4, 5, 6, 7, 8]
flip
Convert between rows and columns. A good way to visualize this operation is holding a card by the top-left and bottom-right corners and flipping it over.
import { flip } from '@bedard/utils'
flip([
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
]) // [[0, 3, 6], [1, 4, 7], [2, 5, 8]]
hslToRgb
Convert [hue, saturation, lightness, alpha?]
to [red, green, blue, alpha]
values.
import { hslToRgb } from '@bedard/utils'
hslToRgb([0, 1, 0.5]) // [255, 0, 0, 1]
intersect
Intersect two-dimensional lines. Returns undefined
if lines are parellel.
import { intersect } from '@bedard/utils'
intersect([[-1, 0], [1, 0]], [[0, 1], [0, -1]]) // [0, 0]
isEmail
A fairly permissive email test where the value must be shaped [email protected]
, and contain exactly one @
characters.
import { isEmail } from '@bedard/utils'
isEmail('[email protected]') // true
isEven
Test if a number is even.
import { isEven } from '@bedard/utils'
isEven(2) // true
keys
Type-safe wrapper around Object.keys
import { keys } from '@bedard/utils'
keys({ foo: 'bar' }) // ['foo']
lerp
Linear interpolation between numbers.
import { lerp } from '@bedard/utils'
lerp(0, 10, 0.5) // 5
lerpColors
Linear interpolation between colors.
import { lerpColors } from '@bedard/utils'
lerpColors('#000000', '#ffffff') // '#808080'
lerpVectors
Linear interpolation between two vectors. This function is similar to bilerp
, but for vectors of any size, or even vectors of different sizes.
import { lerpVectors } from '@bedard/utils'
lerpVectors([0, 0, 0], [1, 2, 3], 0.5) // [0.5, 1, 1.5]
measure
Measure the distance between two vectors.
import { measure } from '@bedard/utils'
// arguments can be provided as a pair of vectors
measure([0, 0], [3, 4]) // 5
// or as a single line argument
measure([[0, 0], [3, 4]]) // 5
parse
A type-safe wrapper around JSON.parse
. This utility is complimented by stringify
, Json
, and UnwrapJson
.
import { stringify } from '@bedard/utils'
stringify({ foo: 'bar' }) // '{"foo":"bar"}' as Json<{ foo: string }>
parseColor
Parse an RGB string to [red, green, blue, alpha]
values. An error will be thrown if the value is not valid.
import { parseColor } from '@bedard/utils'
parseColor('#123456') // [18, 52, 86, 0]
polygon
Create a regular polygon. The first argument defines the number of points, with the second defining the circumradius. Points start from the 12 o'clock position, and rotate counter-clockwise around the origin.
import { polygon } from '@bedard/utils'
polygon(4, 1) // [[0, 1], [-1, 0], [0, -1], [1, 0]] (approximate)
radiansToDegrees
Convert radians to degrees.
import { radiansToDegrees } from '@bedard/utils'
radiansToDegrees(Math.PI) // 180
roll
Roll the start of an array forwards or backwards.
import { roll } from '@bedard/utils'
roll([0, 1, 2], 1) // [1, 2, 0]
rgbToHsl
Convert [red, green, blue, alpha?]
to [hue, saturation, lightness, alpha]
values.
import { rgbToHsl } from '@bedard/utils'
rgbToHsl([255, 0, 0]) // [0, 1, 0.5, 1]
rotateMatrix
Rotate a square matrix. Positive values apply clockwise rotations.
import { rotateMatrix } from '@bedard/utils'
rotateMatrix([
0, 1, 2,
3, 4, 5,
6, 7, 8,
], 1) // [6, 3, 0, 7, 4, 1, 8, 5, 2]
rotateVector
Rotate a vector counter-clockwise around the origin.
import { rotateVector } from '@bedard/utils'
rotateVector([0, 1], 90) // [-1, 0] (approximate)
rows
Chunk a square matrix into rows. Note that the source matrix must be provided in row-major order.
import { rows } from '@bedard/utils'
rows([
0, 1, 2,
3, 4, 5,
6, 7, 8,
]) // [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
scale
Multiple a vector by a number.
import { scale } from '@bedard/utils'
scale([1, 2], 2) // [2, 4]
slope
Calculate the slope of a line.
import { slope } from '@bedard/utils'
// arguments can be provided as a pair of vectors
slope([0, 0], [1, 1]) // 1
// or as a single line argument
slope([[0, 0], [1, 1]]) // 1
stringify
A type-safe wrapper around JSON.stringify
. This utility is complimented by parse
, Json
, and UnwrapJson
import { parse, stringify } from '@bedard/utils'
const json = stringify({ foo: 'bar' })
const obj = parse(json) // { foo: string }
timeout
Resolve a promise after a given duration
import { timeout } from '@bedard/utils'
await timeout(100)
stringifyColor
Convert [red, green, blue, alpha?]
values to string using hexadecimal notation.
import { stringifyColor } from '@bedard/utils'
stringifyColor([255, 0, 0]) // #ff0000
toKeyedObjects
Create keyed objects from an array.
import { toKeyedObjects } from '@bedard/utils'
toKeyedObjects([1, 2], 'foo') // [{ foo: 1 }, { foo: 2 }]
Types
Abs<T>
AddDigits<T, U>
AllEqual<Sources, Value>
AND<T, U>
Bit
BreakWords<T>
Byte
CamelCase<T>
CamelCaseKeys<T>
CamelCaseKeysDeep<T>
Decimal
Difference<A, B>
Digits<T>
Either<T, U>
Equal<A, B>
Expect<T>
First<T>
Hex
HexColor<T>
Intersection<A, B>
IsFloat<T>
IsInteger<T>
IsNegative<T>
IsPositive<T>
Join<Parts, Delimeter>
Json<T>
KebabCase<T>
KebabCaseKeys<T>
KebabCaseKeysDeep<T>
Last<T>
LastDigit<T>
Line<T>
MapCapitalize<T>
MapLowercase<T>
MapUppercase<T>
MaybeArray<T>
Methods<T>
MUX<T, U, S>
NAND<T, U>
Negate<T>
NOR<T, U>
NOT<T, U>
Not<T>
OmitStartsWith<T, U>
OmitType<T, U>
Opaque<T, Token>
OptionalKeys<T, U>
OR<T, U>
PadDigits<T, U>
PascalCase<T>
PascalCaseKeys<T>
PascalCaseKeysDeep<T>
PickStartsWith<T, U>
PickType<T, U>
Pop<T>
Properties<T>
RequiredKeys<T, U>
RgbColor<T>
ScreamingSnakeCase<T>
ScreamingSnakeCaseKeys<T>
ScreamingSnakeCaseKeysDeep<T>
Shift<T>
SnakeCase<T>
SnakeCaseKeys<T>
SnakeCaseKeysDeep<T>
Split<Source, Delimeter>
StartsWith<T, U>
SymmetricDifference<A, B>
ToNumber<T>
Transparent<T>
Trim<T>
UnwrapJson<T>
UnwrapOpaque<T>
ValueOf<T>
Vec<T>
Without<A, B>
XNOR<T, U>
XOR<T, U>
Abs<T>
Type the absolute value of T
import { Abs } from '@bedard/utils'
type Test = Abs<-5> // 5
AddDigits<T, U>
Add two decimal digits
import { AddDigits } from '@bedard/utils'
type Test = AddDigits<1, 2> // 3
AllEqual<Sources, Value>
Types true
if all Sources
equal Value
.
import { AllEqual } from '@bedard/utils'
type Test1 = AllEqual<[1, 1], 1> // true
type Test2 = AllEqual<[1, 2], 1> // false
AND<T, U>
Logical AND gate
import { AND } from '@bedard/utils'
type Test = AND<1, 1> // 1
Bit
Union of bit values
import { Bit } from '@bedard/utils'
type Test = Bit // 0 | 1
BreakWords<T>
Explode a string by common word breaks. This currently includes spaces, hyphens, underscores, and casing changes.
import { BreakWords } from '@bedard/utils'
type Test = BreakWords<'one twoThree-four'> // ['one', 'two', 'Three', 'four']
Byte
A union of all numbers that can be represented by a single byte (0 - 255).
import { Byte } from '@bedard/utils'
const n: Byte = 255
CamelCase<T>
Convert a string to camel case.
import { CamelCase } from '@bedard/utils'
type Test = CamelCase<'foo-bar'> // 'fooBar'
CamelCaseKeys<T>
Camel case object keys.
import { CamelCaseKeys } from '@bedard/utils'
type Test = CamelCaseKeys<{ foo_bar: any }> // { fooBar: any }
CamelCaseKeysDeep<T>
Deeply camel case object keys.
import { CamelCaseKeysDeep } from '@bedard/utils'
type Test = CamelCaseKeysDeep<{ foo_bar: { one_two: any }}> // { fooBar: { oneTwo: any }}
Decimal
Union of decimal values
import { Decimal } from '@bedard/utils'
type Test = Decimal // 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Digits<T>
Explode the digits of a positive integer
import { Digits } from '@bedard/utils'
type Test = Digits<123> // [1, 2, 3]
Difference<A, B>
Elements of A
that are not elements of B
. For unions, this is the same as the Exclude
utility.
import { Difference } from '@bedard/utils'
type Test = Difference<{ a: any, b: any }, { b: any, c: any }> // { a: any }
Either<T, U>
Create an exclusive or between two types. Note that for objects, this differs from a union type in that keys are strictly matched.
import { Either } from '@bedard/utils'
type Test = Either<{ foo: any }, { bar: any }>
const a: Test = { foo } // pass
const b: Test = { bar } // pass
const c: Test = { foo, bar } // fail
Additionally, a tuple can be provided for a chained XOR.
type Test = XOR<[1, 2, 3]>
const a: Test = 1 // pass
const b: Test = 2 // pass
const c: Test = 3 // pass
const d: Test = 4 // fail
Equal<A, B>
Types true
if A
and B
are equal. This is mainly used with Expect
to verify that types are working as expected. See NotEqual
for the inverse of this type.
import { Expect, Equal } from '@bedard/utils'
type Test = Expect<Equal<number, number>>
Expect<T>
Verify that T
is true
. This allows for assertions to be made using the type system. See Equal
and NotEqual
for more usage examples.
import { Expect } from '@bedard/utils'
type Test = Expect<true>
First<T>
Extract the first element of a string or array.
import { First } from '@bedard/utils'
type Test1 = First<'abc'> // 'a'
type Test2 = First<[1, 2, 3]>, // 1
Hex
A hexadecimal character
import { Hex } from '@bedard/utils'
const char: Hex = 'a'
HexColor<T>
Validate a hexadecimal color value
import { HexColor } from '@bedard/utils'
const color = <T>(val: HexColor<T>) => val
color('#abc')
Intersection<A, B>
The intersection of A
and B
, giving preference to A
.
import { Intersection } from '@bedard/utils'
type Test = Intersection<{ a: any, b: number }, { c: string, d: any }> // { b: number }
IsFloat<T>
Test if number is a float
import { IsInteger } from '@bedard/utils'
type Test = IsFloat<1.5> // true
IsInteger<T>
Test if number is an integer
import { IsInteger } from '@bedard/utils'
type Test = IsInteger<1> // true
IsNegative<T>
Test if number is less than zero
import { IsNegative } from '@bedard/utils'
type Test = IsNegative<-1> // true
IsPositive<T>
Test if number is greater than zero
import { IsPositive } from '@bedard/utils'
type Test = IsPositive<1> // true
Join<Parts, Delimeter>
Join Parts
by Delimeter
. This type is the opposite of Split
.
import { Join } from '@bedard/utils'
type Test1 = Join<['a', 'b', 'c']> // 'abc'
type Test2 = Join<['a', 'b', 'c'], '.'> // 'a.b.c'
Json<T>
Encodes a JSON string with underlying type information. This utility is complimented by parse
, stringify
, and UnwrapJson
.
import { Json } from '@bedard/utils'
type Test = Json<{ foo: 'bar' }> // string
KebabCase<T>
Convert a string to kebab case.
import { KebabCase } from '@bedard/utils'
type Test = KebabCase<'fooBar'> // 'foo-bar'
KebabCaseKeys<T>
Kebab case object keys.
import { KebabCaseKeys } from '@bedard/utils'
type Test = KebabCaseKeys<{ foo_bar: any }> // { 'foo-bar': any }
KebabCaseKeysDeep<T>
Deeply kebab case object keys.
import { KebabCaseKeysDeep } from '@bedard/utils'
type Test = KebabCaseKeysDeep<{ foo_bar: { one_two: any }}> // { 'foo-bar': { 'one-two': any }}
Last<T>
Extract the last element of a string or array.
import { Last } from '@bedard/utils'
type Test1 = Last<'abc'> // 'c'
type Test2 = Last<[1, 2, 3]>, // 3
LastDigit<T>
Get the last digit of a number
import { LastDigit } from '@bedard/utils'
type Test1 = LastDigit<12> // 2
type Test2 = LastDigit<1.5> // 5
Line<T>
Describes a straight line between two vectors of length T
.
import { Line } from '@bedard/utils'
type Test = Line<2> // [[number, number], [number, number]]
MapCapitalize<T>
Capitalize the first letter of each string.
import { MapCapitalize } from '@bedard/utils'
type Test = MapLowercase<['foo', 'bar']> // ['Foo', 'Bar']
MapLowercase<T>
Map strings to lowercase.
import { MapLowercase } from '@bedard/utils'
type Test = MapLowercase<['A', 'B']> // ['a', 'b']
MapUppercase<T>
Map strings to uppercase.
import { MapUppercase } from '@bedard/utils'
type Test = MapUppercase<['a', 'b']> // ['A', 'B']
MaybeArray<T>
Singular or array of T
import { MaybeArray } from '@bedard/utils'
type Test = MaybeArray<number> // number | number[]
Methods<T>
Create a string union of methods from T
. This is the inverse of Properties<T>
import { Methods } from '@bedard/utils'
type Test = Methods<{ foo: string, bar(): any }> // 'bar'
MUX<T, U, S>
Logical MUX gate
import { MUX } from '@bedard/utils'
type Test = MUX<1, 0, 0> // 1
NAND<T, U>
Logical NAND gate
import { NAND } from '@bedard/utils'
type Test = NAND<0, 0> // 1
Negate<T>
Reverse the sign of a number
import { Negate } from '@bedard/utils'
type Test = Negate<1> // -1
NOR<T, U>
Logical NOR gate
import { NOR } from '@bedard/utils'
type Test = NOR<0, 0> // 1
NOT<T>
Reverse the Bit
value of T
.
import { NOT } from '@bedard/utils'
type Test = NOT<1> // /0
Not<T>
Reverse the boolean
value of T
.
import { Not } from '@bedard/utils'
type Test = Not<true> // false
OmitStartsWith<T, U>
Omit keys of T
that start with U
.
import { OmitStartsWith } from '@bedard/utils'
type Test = OmitStartsWith<{ FooOne: void; FooTwo: void; BarThree: void }, 'Bar'> // { FooOne: void; FooTwo: void }
OmitType<T, U>
Omit keys of T
that extend U
. This is the inverse of PickType<T, U>
.
import { OmitType } from '@bedard/utils'
type Test = OmitType<{ foo: string, bar: number }, string> // { bar: number }
Opaque<T, Token>
Opaque type T
with an optional Token
. For more on opaque types, this article is a great place to start.
import { Opaque } from '@bedard/utils'
type USD = Opaque<number, 'usd'>
const dollars = 5 as USD
OptionalKeys<T, U>
Get optional keys from T
, or make keys U
of T
optional.
import { OptionalKeys } from '@bedard/utils'
type Test1 = OptionalKeys<{ foo?: any, bar: any }> // 'foo'
type Test2 = OptionalKeys<{ foo: any, bar: any }, 'foo'> // { foo?: any, bar: any }
OR<T, U>
Logical OR gate
import { OR } from '@bedard/utils'
type Test = OR<0, 1> // 1
PadDigits<T, U>
Pad two numeric vectors so they are the same size
import { PadVec } from '@bedard/utils'
type Test = PadDigits<[1, 2], [3]> // [ [1, 2], [0, 3] ]
PascalCase<T>
Convert a string to pascal case.
import { PascalCase } from '@bedard/utils'
type Test = PascalCase<'foo-bar'> // 'FooBar'
PascalCaseKeys<T>
Kebab case object keys.
import { PascalCaseKeys } from '@bedard/utils'
type Test = PascalCaseKeys<{ foo_bar: any }> // { 'foo-bar': any }
PascalCaseKeysDeep<T>
Deeply pascal case object keys.
import { PascalCaseKeysDeep } from '@bedard/utils'
type Test = PascalCaseKeysDeep<{ foo_bar: { one_two: any }}> // { FooBar: { OneTwo: any }}
PickStartsWith<T, U>
Pick keys of T
that start with U
.
import { PickStartsWith } from '@bedard/utils'
type Test = PickStartsWith<{ FooOne: void; FooTwo: void ; Bar: void }, 'Foo'> // { FooOne: void; FooTwo: void }
PickType<T, U>
Pick keys of T
that extend U
. This is the inverse of OmitType<T, U>
.
import { PickType } from '@bedard/utils'
type Test = PickType<{ foo: string, bar: number }, string> // { foo: string }
Pop<T>
Remove the last element of T
.
import { Pop } from '@bedard/utils'
type Test = Pop<['foo', 'bar', 'baz']> // ['foo', 'bar']
Properties<T>
Create a string union of properties from T
. This is the inverse of Methods<T>
.
import { Properties } from '@bedard/utils'
type Test = Properties<{ foo: string, bar(): any }> // 'foo'
RequiredKeys<T, U>
Get required keys from T
, or make keys U
of T
required.
import { RequiredKeys } from '@bedard/utils'
type Test = RequiredKeys<{ foo: any, bar?: any }> // 'foo'
type Test = RequiredKeys<{ foo?: any, bar?: any }, 'foo'> // { foo: any, bar?: any }
RgbColor<T>
Validate a rgb color
import { RgbColor } from '@bedard/utils'
const rgb = <T>(color: RgbColor<T>) => color
rgb('rgb(0, 0, 0)')
ScreamingSnakeCase<T>
Convert a string to screaming snake case.
import { ScreamingSnakeCase } from '@bedard/utils'
type Test = ScreamingSnakeCase<'fooBar'> // 'FOO_BAR'
ScreamingSnakeCaseKeys<T>
Screaming snake case object keys.
import { ScreamingSnakeCaseKeys } from '@bedard/utils'
type Test = ScreamingSnakeCaseKeys<{ foo_bar: any }> // { FOO_BAR: any }
ScreamingSnakeCaseKeysDeep<T>
Deeply screaming snake case object keys.
import { ScreamingSnakeCaseKeysDeep } from '@bedard/utils'
type Test = ScreamingSnakeCaseKeysDeep<{ foo_bar: { one_two: any }}> // { FOO_BAR: { ONE_TWO: any }}
Shift<T>
Remove the first element of T
.
import { Shift } from '@bedard/utils'
type Test = Shift<['foo', 'bar', 'baz']> // ['bar', 'baz']
SnakeCase<T>
Convert a string to snake case.
import { SnakeCase } from '@bedard/utils'
type Test = SnakeCase<'fooBar'> // 'foo_bar'
SnakeCaseKeys<T>
Snake case object keys.
import { SnakeCaseKeys } from '@bedard/utils'
type Test = SnakeCaseKeys<{ fooBar: any }> // { foo_bar: any }
SnakeCaseKeysDeep<T>
Deeply snake case object keys.
import { SnakeCaseKeysDeep } from '@bedard/utils'
type Test = SnakeCaseKeysDeep<{ fooBar: { oneTwo: any }}> // { foo_bar: { one_two: any }}
Split<Source, Delimeter>
Split Source
by Delimeter
. This type is the opposite of Join
. Note that to split by multiple delimeters the second argument must be a string[]
, as unions will create a distributive conditional type.
import { Split } from '@bedard/utils'
type Test1 = Split<'abc'> // ['a', 'b', 'c']
type Test2 = Split<'a.b.c', '.'> // ['a', 'b', 'c']
type Test3 = Split<'a.b-c', ['.', '-']> // ['a', 'b', 'c']
StartsWith<T, U>
Types true
if T
starts with U
.
import { StartsWith } from '@bedard/utils'
type Test = StartsWith<'FooBar', 'Foo'> // true
SymmetricDifference<A, B>
The symmetric difference of A
and B
.
import { SymmetricDifference } from '@bedard/utils'
type Test1 = SymmetricDifference<'a' | 'b', 'b' | 'c'> // 'a' | 'c'
type Test2 = SymmetricDifference<{ a: any, b: any }, { b: any, c: any }> // { a: any, c: any }
ToNumber<T>
Convert numeric string
to number
import { ToNumber } from '@bedard/types'
type Test = ToNumber<'123'> // 123
Transparent<T>
A type that does not encode any additional data. This is the inverse of Opaque<T>
.
import { Transparent } from '@bedard/utils'
type Test = Transparent<string>
Trim<T>
Trim leading and trailing whitespace
import { Trim } from '@bedard/utils'
type Test = Trim<' foo bar '> // 'foo bar'
UnwrapOpaque<T>
Unwrap the underlying data of an Opaque<T>
type.
import { UnwrapOpaque } from '@bedard/utils'
type Test1 = Opaque<string, 'example'>
type Test2 = UnwrapOpaque<Foo> // string
UnwrapJson<T>
Decodes type information from a Json<T>
string.
import { Json, UnwrapJson } from '@bedard/utils'
type UserJson = Json<{ email: string }> // string
type User = UnwrapJson<UserJson> // { email: string }
ValueOf<T>
Generate a union from the values of T
.
import { ValueOf } from '@bedard/utils'
type Test1 = ValueOf<Array<string>> // string
type Test2 = ValueOf<{ foo: number, bar: string }> // number | string
Vec<T>
Generate a uniform tuple of length T
, with numeric values by default.
import { Vec } from '@bedard/utils'
type Test1 = Vec<3> // [number, number, number]
type Test2 = Vec<3, Thing> // [Thing, Thing, Thing]
Without<A, B>
Prohibit properties of A
and omit properties of B
.
import { Without } from '@bedard/utils'
type Test = Without<{ foo: any, bar: any }, { bar: any }> // { foo?: never }
XNOR<T, U>
Logical XNOR gate
import { XNOR } from '@bedard/types'
type Test = XNOR<0, 0> // 1
XOR<T, U>
Logical XOR gate
import { XOR } from '@bedard/utils'
type Test = XOR<0, 1> // 1
License
Copyright (c) 2021-present, Scott Bedard