@bedard/types
v0.9.0
Published
[![Test status](https://img.shields.io/github/workflow/status/scottbedard/types/Test)](https://github.com/scottbedard/types/actions/workflows/test.yml) [![NPM](https://img.shields.io/npm/v/@bedard/types)](https://www.npmjs.com/package/@bedard/types) [![Li
Downloads
39
Readme
@bedard/types
The goal of this package is to act as an extension to Typescript's built-in utility types. There is currently no runtime, but that may change if type guards are added. I don't anticipate breaking changes, but with that said this is mainly for personal use, so upgrade with caution.
Installation
The recommended way to install this package is through NPM.
npm install @bedard/types
Utility types
AllEqual<Sources, Value>
BreakWords<T>
CamelCase<T>
CamelCaseKeys<T>
CamelCaseKeysDeep<T>
Difference<A, B>
Equal<A, B>
Expect<T>
Extends<A, B>
First<T>
Intersection<A, B>
Join<Parts, Delimeter>
KebabCase<T>
KebabCaseKeys<T>
KebabCaseKeysDeep<T>
Last<T>
MapCapitalize<T>
MapLowercase<T>
MapUppercase<T>
Not<T>
NotEqual<A, B>
Opaque<T, Token>
PascalCase<T>
PascalCaseKeys<T>
PascalCaseKeysDeep<T>
Pop<T>
ScreamingSnakeCase<T>
ScreamingSnakeCaseKeys<T>
ScreamingSnakeCaseKeysDeep<T>
Shift<T>
SnakeCase<T>
SnakeCaseKeys<T>
SnakeCaseKeysDeep<T>
Split<Source, Delimeter>
SymmetricDifference<A, B>
Transparent<T>
ValueOf<T>
Without<A, B>
XOR<A, B>
AllEqual<Sources, Value>
Types true
if all Sources
equal Value
.
import { AllEqual } from '@bedard/types'
type Good = AllEqual<[1, 1], 1> // true
type Bad = AllEqual<[1, 2], 1> // false
BreakWords<T>
Explode a string by common word breaks. This currently includes spaces, hyphens, underscores, and casing changes.
import { BreakWords } from '@bedard/types'
type Words = BreakWords<'one twoThree-four'> // ['one', 'two', 'Three', 'four']
CamelCase<T>
Convert a string to camel case.
import { CamelCase } from '@bedard/types'
type Str = CamelCase<'foo-bar'> // 'fooBar'
CamelCaseKeys<T>
Camel case object keys.
import { CamelCaseKeys } from '@bedard/types'
type Obj = CamelCaseKeys<{ foo_bar: any }> // { fooBar: any }
CamelCaseKeysDeep<T>
Deeply camel case object keys.
import { CamelCaseKeysDeep } from '@bedard/types'
type Obj = CamelCaseKeysDeep<{ foo_bar: { one_two: any }}> // { fooBar: { oneTwo: any }}
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/types'
type Left = Difference<{ a: any, b: any }, { b: any, c: any }> // { a: any }
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/types'
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/types'
type Test = Expect<true>
Extends<A, B>
Types true
if A
extends B
.
import { Extends } from '@bedard/types'
type Test = Extends<'foo', string> // true
First<T>
Extract the first element of a string or array.
import { First } from '@bedard/types'
type FirstChar = First<'abc'> // 'a'
type FirstItem = First<[1, 2, 3]>, // 1
Intersection<A, B>
The intersection of A
and B
, giving preference to A
.
import { Intersection } from '@bedard/types'
type Shared = Intersection<{ a: any, b: number }, { c: string, d: any }> // { b: number }
Join<Parts, Delimeter>
Join Parts
by Delimeter
. This type is the opposite of Split
.
import { Join } from '@bedard/types'
type Str = Join<['a', 'b', 'c']> // 'abc'
type Parts = Join<['a', 'b', 'c'], '.'> // 'a.b.c'
KebabCase<T>
Convert a string to kebab case.
import { KebabCase } from '@bedard/types'
type Str = KebabCase<'fooBar'> // 'foo-bar'
KebabCaseKeys<T>
Kebab case object keys.
import { KebabCaseKeys } from '@bedard/types'
type Obj = KebabCaseKeys<{ foo_bar: any }> // { 'foo-bar': any }
KebabCaseKeysDeep<T>
Deeply kebab case object keys.
import { KebabCaseKeysDeep } from '@bedard/types'
type Obj = 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/types'
type LastChar = Last<'abc'> // 'c'
type LastItem = Last<[1, 2, 3]>, // 3
MapCapitalize<T>
Capitalize the first letter of each string.
import { MapCapitalize } from '@bedard/types'
type Capitalized = MapLowercase<['foo', 'bar']> // ['Foo', 'Bar']
MapLowercase<T>
Map strings to lowercase.
import { MapLowercase } from '@bedard/types'
type Lower = MapLowercase<['A', 'B']> // ['a', 'b']
MapUppercase<T>
Map strings to uppercase.
import { MapUppercase } from '@bedard/types'
type Upper = MapUppercase<['a', 'b']> // ['A', 'B']
Not<T>
Reverse the boolean value of T
.
import { Not } from '@bedard/types'
type Test = Not<true> // false
NotEqual<A, B>
Types true
if A
does not equal B
. This type is mainly used with Expect
to verify that types are working as expected. See Equal
for the inverse of this type.
import { Expect, NotEqual } from '@bedard/types'
type Test = Expect<NotEqual<number, string>>
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/types'
type USD = Opaque<number, 'usd'>
const dollars = 5 as USD
PascalCase<T>
Convert a string to pascal case.
import { PascalCase } from '@bedard/types'
type Str = PascalCase<'foo-bar'> // 'FooBar'
PascalCaseKeys<T>
Kebab case object keys.
import { PascalCaseKeys } from '@bedard/types'
type Obj = PascalCaseKeys<{ foo_bar: any }> // { 'foo-bar': any }
PascalCaseKeysDeep<T>
Deeply pascal case object keys.
import { PascalCaseKeysDeep } from '@bedard/types'
type Obj = PascalCaseKeysDeep<{ foo_bar: { one_two: any }}> // { FooBar: { OneTwo: any }}
Pop<T>
Remove the last element of T
.
import { Pop } from '@bedard/types'
type Items = Pop<['foo', 'bar', 'baz']> // ['foo', 'bar']
ScreamingSnakeCase<T>
Convert a string to screaming snake case.
import { ScreamingSnakeCase } from '@bedard/types'
type Str = ScreamingSnakeCase<'fooBar'> // 'FOO_BAR'
ScreamingSnakeCaseKeys<T>
Screaming snake case object keys.
import { ScreamingSnakeCaseKeys } from '@bedard/types'
type Obj = ScreamingSnakeCaseKeys<{ foo_bar: any }> // { FOO_BAR: any }
ScreamingSnakeCaseKeysDeep<T>
Deeply screaming snake case object keys.
import { ScreamingSnakeCaseKeysDeep } from '@bedard/types'
type Obj = ScreamingSnakeCaseKeysDeep<{ foo_bar: { one_two: any }}> // { FOO_BAR: { ONE_TWO: any }}
Shift<T>
Remove the first element of T
.
import { Shift } from '@bedard/types'
type Items = Shift<['foo', 'bar', 'baz']> // ['bar', 'baz']
SnakeCase<T>
Convert a string to snake case.
import { SnakeCase } from '@bedard/types'
type Str = SnakeCase<'fooBar'> // 'foo_bar'
SnakeCaseKeys<T>
Snake case object keys.
import { SnakeCaseKeys } from '@bedard/types'
type Obj = SnakeCaseKeys<{ fooBar: any }> // { foo_bar: any }
SnakeCaseKeysDeep<T>
Deeply snake case object keys.
import { SnakeCaseKeysDeep } from '@bedard/types'
type Obj = 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/types'
type Characters = Split<'abc'> // ['a', 'b', 'c']
type SingleDelimeter = Split<'a.b.c', '.'> // ['a', 'b', 'c']
type MultipleDelimeters = Split<'a.b-c', ['.', '-']> // ['a', 'b', 'c']
SymmetricDifference<A, B>
The symmetric difference of A
and B
.
import { SymmetricDifference } from '@bedard/types'
type OuterSet = SymmetricDifference<'a' | 'b', 'b' | 'c'> // 'a' | 'c'
type OuterObj= SymmetricDifference<{ a: any, b: any }, { b: any, c: any }> // { a: any, c: any }
Transparent<T>
A type that does not encode any additional data. This type the inverse of Opaque<T>
.
import { Transparent } from '@bedard/types'
type NonOpaqueString = Transparent<string>
ValueOf<T>
Generate a union from the values of T
.
import { ValueOf } from '@bedard/types'
type ArrayValues = ValueOf<Array<string>> // string
type ObjectValues = ValueOf<{ foo: number, bar: string }> // number | string
Without<A, B>
Prohibit properties of A
and omit properties of B
.
import { Without } from '@bedard/types'
type FooWithoutBar = Without<{ foo: any, bar: any }, { bar: any }> // { foo?: never }
XOR<A, B>
Create an exclusive or between two types. Note that for objects, this differs from a union type in that keys are strictly matched.
import { XOR } from '@bedard/types'
type FooOrBar = XOR<{ foo: any }, { bar: any }>
const a: FooOrBar = { foo } // pass
const b: FooOrBar = { bar } // pass
const c: FooOrBar = { foo, bar } // fail