@bedard/types
v0.9.0
Published
[](https://github.com/scottbedard/types/actions/workflows/test.yml) [](https://www.npmjs.com/package/@bedard/types) [![Li
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/typesUtility 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> // falseBreakWords<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> // trueFirst<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]>, // 1Intersection<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]>, // 3MapCapitalize<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> // falseNotEqual<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 USDPascalCase<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 | stringWithout<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