type-plus
v8.0.0
Published
Provides additional types for TypeScript.
Maintainers
Readme
type-plus
More than 200 type utilities for TypeScript for applications, library, and type-level programming.
What's new in 8.0
type-plus 8.0 is a major release. It needs TypeScript 5.4 or later, and Node.js 20 or later
for the runtime functions. The main changes from 7.x:
- Branching types take an options object (
{ $then, $else, selection, exact, distributive }) instead of positionalThenandElseparameters. - The
XxxTypefilter types, theIsStrictXxxpredicates and the numeric filter types are removed. Use theIsXxxpredicates with{ selection: 'filter' }or{ exact: true }. Equal,CanAssignand theExtendfamily are removed. UseIsEqualandAssignable.- The top-level
Partial,Required,PickandOmitmove toObjectPlus, and the other deprecated exports are removed. canAssign(), the one-argumentisType()and theassertTypemembers are removed.assertType()requires a validator.- The
*Plusnamespaces are type-only. Import them withimport type. - Several predicates now distribute over unions, and a few results changed.
Most of the upgrade is mechanical. The v7 to v8 migration guide lists every breaking change with a before and after example, including the changed results that a rename will not surface.
Table of Contents
- Table of Contents
- What's new in 8.0
- Installation
- What's in the package?
- Assertion Function
- Type Guard
- Type Utilities
- Type Specific Utilities
- Testing Utilities
- Constant Types
- JSON Support
- Type manipulation
- Type Predicates
- Math
- Utility Functions
- Nominal Types
- Functional Types
- Attribution
- Useful Tips
- Similar projects
Installation
npm install type-plus
yarn add type-plus
pnpm add type-plusWhat's in the package?
With over 200 types in type-plus,
it can become difficult to find the types you need.
Also, some types need to be updated as TypeScript continue to evolve.
Currently, we are updating type-plus with the following objective:
- Update organization
- Update documentation
- Clean up and deprecate types
- Require TypeScript 5.4 or later (breaking change in 8.0)
Update organization
Top-level exports of type-plus will contain types and functions that do not expect the input to be a specific type. For example,
isType()andtestType()- Type filters and predicates such as
IsAnyorIsArray
It can also have types and functions for specific types if it is a common convention, or the is no ambiguity, or for backwards compatibility purpose.
Other type specific utilities will be added under their respective *Plus namespaces such as ArrayPlus.At or NumericPlus.IsPositive.
Update documentation
Each type and utility function in type-plus will be updated to include examples and tags to indicate its category and behavior.
Each tag has an associated icon:
- 👽 alias: Alias of another type
- 🚦 assertion: assertion function
- 🔢 customizable: the behavior of the type is customizable.
- 💀 deprecated: deprecated and will be removed soon
- 🌪️ filter: a.k.a. parse These types perform some kind of test. If the input passes the test, the input is returned. Otherwise, it returns
never - 🛡️ guard: type guard function
- 💥 immediate: the effect of the type can be observed immediately during development
- ㊙️ internal: the type is internal and should not be used directly
- 🏃 runtime: the function has runtime effect
- 🩳 shortcut: Shortcut or convenient types
- 🧪 testing: the type or function are designed for test
- ⚗️ transform: these types transforms the input to another category
- 🧰 type util: types for building types
- 🦴 utilities: provide various functionalities
- 🎭 predicate: a.k.a. predicate or logical. These types perform some kind of test. If the input passes the test, it returns
trueorfalse
Assertion Function
🚦 assertion, 🏃 runtime: throws a TypeError unless validator passes, and narrows subject to T.
The throwing counterpart of isType(), for pre- and post-conditions.
assertType<string>(value, (v) => typeof v === 'string', 'value must be a string')
value // string🗑️ changed in 8.0.0: the validator is required. The no-validator overload, the constructor overload,
and the members (assertType.isX/noX/as/custom) are removed; they checked nothing at runtime.
Use x satisfies T for a compile-time check, and testType in tests.
Type Guard
User-defined type guard functions is a function which its return type is specified as x is T.
🛡️ guard: a generic type guard function
🗑️ removed in 8.0.0: the one-argument form isType<T>(subject).
Use subject satisfies T instead. isType(subject, validator) stays.
Type Utilities
🎭 predicate, 🔢 customizable: A and B are the same type.
🎭 predicate, 🔢 customizable: A and B are not the same type.
Equal and the old positional IsEqual/IsNotEqual/NotEqual were removed in 8.0.0.
🎭 predicate, 🔢 customizable: A is assignable to B.
🎭 predicate, 🔢 customizable: A is not assignable to B.
🎭 predicate, 🔢 customizable: T is a scalar literal.
🎭 predicate, 🔢 customizable: T is not a scalar literal.
🎭 predicate, 🔢 customizable: T is the empty object type {}.
🎭 predicate, 🔢 customizable: T is not the empty object type {}.
Extendable, NotExtendable, IsExtend, IsNotExtend, CanAssign, StrictCanAssign and
IsAssign were removed in 8.0.0. Use Assignable / NotAssignable instead:
Extendable<A, B>→Assignable.$<A, B, { selection: 'filter' }>NotExtendable<A, B>→NotAssignable.$<A, B, { selection: 'filter' }>IsExtend<A, B, Then, Else>→Assignable.$<A, B, { $then: Then; $else: Else }>IsNotExtend<A, B, Then, Else>→NotAssignable.$<A, B, { $then: Then; $else: Else }>CanAssign<A, B>/IsAssign<A, B>→Assignable<A, B>StrictCanAssign<A, B>→Assignable<A, B, { distributive: false }>
A typical usage is using Assignable with testType:
testType.false<Assignable<boolean, { a: string }>>(true)
testType.true<Assignable<{ a: string; b: number }, { a: string }>>(true)any, unknown and never follow TypeScript's own assignability relation:
any is assignable to everything but never and everything is assignable to any,
unknown is assignable only to any and unknown,
and never is assignable to everything.
testType.true<Assignable<any, number>>(true)
testType.true<Assignable<number, any>>(true)
testType.false<Assignable<unknown, number>>(true)
testType.true<Assignable<never, number>>(true)Assignable<number | string, number, { distributive: false }> // false
Assignable<number | string, number | string, { distributive: false }> // true🗑️ removed in 8.0.0: the canAssign<T>() function. It checked nothing at runtime:
| Removed | In a test | In code |
| --- | --- | --- |
| canAssign<T>()(v) | testType.canAssign<typeof v, T>(true) | v satisfies T |
| canAssign<T>(false)(v) | testType.canAssign<typeof v, T>(false) | |
Type Specific Utilities
type-plus provides type checking utilities for every type.
Each type has at least 2 type checks.
Using string as an example, there are IsString<T> and IsNotString<T>.
The { selection: 'filter' } option returns T or never instead of true or false,
and { exact: true } matches only the wide type.
Some types will have more checks, such as boolean has IsTrue<T> and IsFalse<T>.
You can learn more in their respective sections:
any
🎭 predicate, 🔢 customizable: T is any.
🎭 predicate, 🔢 customizable: T is not any.
🎭 predicate, 🔢 customizable: T is exactly any or exactly never.
🎭 predicate, 🔢 customizable: T is neither exactly any nor exactly never.
Array
🎭 predicate, 🔢 customizable: T is an array, excluding tuple.
🎭 predicate, 🔢 customizable: T is not an array, excluding tuple.
🦴 utilities: the element of A at the positive or negative index N.
🦴 utilities, 🔢 customizable: the first entry of the tuple, or the element type of the array T.
🦴 utilities, 🔢 customizable: the last entry of the tuple, or the element type of the array T.
⚗️ transform: keeps the entries of A satisfying Criteria.
🗑️ removed in 8.0.0: KeepMatch — use Filter instead.
🦴 utilities, 🔢 customizable: the first entry of A matching Criteria.
🦴 utilities, 🔢 customizable: the last entry of A matching Criteria.
🎭 predicate, 🔢 customizable: any element of A matches Criteria.
⚗️ transform: pads the start of A with PadWith up to length L.
⚗️ transform: reverses the order of A.
🗑️ removed in 8.0.0: Concat and ArrayPlus.Concat — use the spread tuple [...A, ...B] instead.
⚗️ transform: the intersection of the K properties of the elements of A.
🗑️ removed in 8.0.0: MapToProp — use IntersectOfProps instead.
⚗️ transform: the union of the K properties of the elements of A.
🗑️ removed in 8.0.0: PropUnion — use UnionOfProps instead.
⚗️ transform: the union of the value types in A.
🧰 namespace: the array types. Entries, ElementMatch, IndexAt, IsIndexOutOfBound, IsReadonly and SplitAt are array-only; CommonPropKeys, DropMatch, Filter, Find and PadStart are the array halves of the top-level types that dispatch on A['length']; At, FindLast and Some are the top-level types grouped here too; Reverse keeps a readonly input readonly.
🏃 runtime, 🦴 utilities: an array whose items are narrowed to the provided literals.
🏃 runtime, 🦴 utilities: reduce() with a predicate for early termination.
Union
🎭 predicate, 🔢 customizable: T is a union.
🎭 predicate, 🔢 customizable: T is not a union.
🧰 type util: a union type constrained to a subset of the union T.
bigint
Full reference: Bigint.
🎭 predicate, 🔢 customizable: T is bigint or a bigint literal. With { exact: true }, only bigint itself.
🎭 predicate, 🔢 customizable: T is not bigint nor a bigint literal.
🎭 predicate, 🔢 customizable: T is a bigint literal. bigint itself is not.
🎭 predicate, 🔢 customizable: T is not a bigint literal.
Boolean
🎭 predicate, 🔢 customizable: T is boolean, true or false.
🎭 predicate, 🔢 customizable: T is not boolean.
🎭 predicate, 🔢 customizable: T is true.
🎭 predicate, 🔢 customizable: T is not true.
🎭 predicate, 🔢 customizable: T is false.
🎭 predicate, 🔢 customizable: T is not false.
Function
🎭 predicate, 🔢 customizable: T is Function or a function signature.
🎭 predicate, 🔢 customizable: T is neither Function nor a function signature.
🧰 type util: a constraint matching any function.
⚗️ transform: the function signature of a composite type F.
🏃 runtime, 🦴 utilities: narrow fn to its function signature only.
🏃 runtime, 🦴 utilities: inspect a value and return it. The inspector defaults to console.dir().
Never
🎭 predicate, 🔢 customizable: T is never.
🎭 predicate, 🔢 customizable: T is not never.
Null
🎭 predicate, 🔢 customizable: T is null.
🎭 predicate, 🔢 customizable: T is not null.
🎭 predicate, 🔢 customizable: T is null or a union containing null.
🎭 predicate, 🔢 customizable: T is not null and not a union containing null.
Number
Full reference: Number and Numeric.
🎭 predicate, 🔢 customizable: T is number or a number literal. With { exact: true }, only number itself.
🎭 predicate, 🔢 customizable: T is not number nor a number literal.
🎭 predicate, 🔢 customizable: T is a number literal. number itself is not.
🎭 predicate, 🔢 customizable: T is not a number literal.
Numeric
Widens the number checks to number | bigint and adds the value-shape predicates.
Full reference: Number and Numeric.
👽 alias: number | bigint.
👽 alias: 0 | 0n.
🎭 predicate, 🔢 customizable: T is number or bigint, literals included.
🎭 predicate, 🔢 customizable: T is neither number nor bigint.
🎭 predicate, 🔢 customizable: T is an integer, bigint included. number resolves to boolean.
🎭 predicate, 🔢 customizable: T is not an integer.
🎭 predicate, 🔢 customizable: T is a positive numeric type, zero included. number and bigint resolve to boolean.
🎭 predicate, 🔢 customizable: T is not a positive numeric type.
🎭 predicate, 🔢 customizable: T is a negative numeric type. number and bigint resolve to boolean.
🎭 predicate, 🔢 customizable: T is not a negative numeric type.
On the six above, { exact: true } matches only the wide number and bigint, never a literal.
The *Literal types below are the other half of that split: they match only literals, so
IsPositive<number> is boolean while IsPositiveLiteral<number> is false.
🎭 predicate, 🔢 customizable: T is an integer literal, bigint literals included.
🎭 predicate, 🔢 customizable: T is not an integer literal.
🎭 predicate, 🔢 customizable: T is a positive numeric literal, zero included.
🎭 predicate, 🔢 customizable: T is not a positive numeric literal.
🎭 predicate, 🔢 customizable: T is a negative numeric literal.
🎭 predicate, 🔢 customizable: T is not a negative numeric literal.
⚗️ transform: a string literal to a number literal, or $O['$fail'] when the string is not one.
⚗️ transform: a string literal with the n suffix to a bigint literal, or $O['$fail'] when the string is not one.
⚗️ transform: a string literal to a number or bigint literal, or $O['$fail'] when the string is not one.
⚗️ transform: a number or bigint literal to its string literal form, the inverse of all three casts above.
Object
filterKey()
🦴 utilities: type adjusted filter by key.
findKey()
🦴 utilities: type adjusted find by key.
forEachKey()
🦴 utilities: type adjusted for each by key.
HasKey<T, K>
🦴 utilities: predicate type checking T has key K.
hasKey()
🦴 utilities: function of HasKey.
HasNoKey<T, K, $O>
🎭 predicate, 🔢 customizable: K is not a key of T.
IsRecord<T, $O>
🎭 predicate, 🔢 customizable: T is a record and not an array.
IsNotRecord<T, $O>
🎭 predicate, 🔢 customizable: T is not a record, or is an array.
🦴 utilities: the keys A and B share whose property types disagree.
mapKey()
🦴 utilities: type adjusted map by key.
RecordValue<R>
🦴 utilities: gets the value type Tfrom Record<any, T>
reduceByKey()
🦴 utilities: type adjusted reduce by key.
someKey()
🦴 utilities: type adjusted some by key.
SpreadRecord<A, B>
🦴 utilities: type for {...a, ...b} when both a and b are Record
for array, just do [...A, ...B].
Promise
AwaitedProp<T, V>
🦴 utilities: Awaited on specified props P in T.
isPromise<R>(subject: any)
🦴 utilities: isPromise() type guard.
MaybePromise<T>
🦴 utilities: Alias of T | Promise<T>.
🗑️ removed in 8.0.0: PromiseValue — use the built-in Awaited<T> instead.
PromiseValueMerge<P1, P2, ...P9>
🦴 utilities: Merge the values of multiple promises.
mapSeries()
🦴 utilities: Similar to bluebird.mapSeries() but works with async/await.
transformMaybePromise(value, transformer)
🦴 utilities: Apply the transformer to the value.
It is also exported under MaybePromise.transform().
String
🎭 predicate, 🔢 customizable: T is string or a string literal. With { exact: true }, only string itself.
🎭 predicate, 🔢 customizable: T is neither string nor a string literal.
🎭 predicate, 🔢 customizable: T is a string literal. With { exact: true }, template literals that do not reduce to one are excluded.
🎭 predicate, 🔢 customizable: T is not a string literal.
🎭 predicate, 🔢 customizable: T is a template literal.
🎭 predicate, 🔢 customizable: T is not a template literal.
🎭 predicate, 🔢 customizable: Subject includes Search.
⚗️ transform: split S into a tuple of substrings.
🧰 type util: the string types whose names are too generic to sit on the top level.
Symbol
🎭 predicate, 🔢 customizable: T is symbol.
🎭 predicate, 🔢 customizable: T is not symbol.
Tuple
🎭 predicate, 🔢 customizable: T is a tuple, excluding array.
🎭 predicate, 🔢 customizable: T is not a tuple, excluding array.
🦴 utilities: a tuple of L elements of type T.
㊙️ internal: the accumulator loop behind CreateTuple.
⚗️ transform: the property keys common to every element of T.
⚗️ transform: every entry of the tuple T except the first.
⚗️ transform: drops the first entry of the tuple T.
⚗️ transform: drops the last entry of the tuple T.
⚗️ transform: drops the entries of A matching Criteria.
⚗️ transform, 👽 alias: DropMatch<A, null>.
⚗️ transform, 👽 alias: DropMatch<A, undefined>.
⚗️ transform, 👽 alias: DropMatch<A, null | undefined>.
🧰 namespace: the tuple halves of the five top-level types that dispatch on A['length'] — CommonPropKeys, DropMatch, Filter, Find (behind FindFirst) and PadStart.
🗑️ removed in 8.0.0: the runtime drop() — no replacement. The DropMatch/DropFirst/... types
stay.
Undefined
🎭 predicate, 🔢 customizable: T is undefined.
🎭 predicate, 🔢 customizable: T is not undefined.
🎭 predicate, 🔢 customizable: T is undefined or a union containing undefined.
🎭 predicate, 🔢 customizable: T is not undefined and not a union containing undefined.
unknown
🎭 predicate, 🔢 customizable: T is exactly unknown.
🎭 predicate, 🔢 customizable: T is not exactly unknown.
🧰 type util: T when it is not unknown, otherwise $Unknown.
void
🎭 predicate, 🔢 customizable: T is void.
🎭 predicate, 🔢 customizable: T is not void.
🎭 predicate, 🔢 customizable: T is void or a union containing void.
🎭 predicate, 🔢 customizable: T is not void and not a union containing void.
Testing Utilities
type-plus provides some testing utilities to help you test your types.
They are exported from the type-plus/testing entry, not from type-plus.
One of the key utilities is testType.
import { testType } from 'type-plus/testing'
testType.any<T>(true) // T is `any`
testType.equal<A, B>(true) // A is equal to B
testType.never<T>(false) // T is not `never`To reuse a check across tests, extract it with the deferred form and assert it at the call site:
import { testType } from 'type-plus/testing'
function testMyType<T>() {
return [testType.defer.string<T>(), testType.defer.not.never<T>()]
}
testType.assert(testMyType<'a'>())You can learn more about them in the docs.
testType is the testing API for types. It belongs in test files: in code, use satisfies for a
compile-time check, and isType() or assertType() with a validator for a runtime one.
The older helpers that overlapped it were removed in 8.0.0:
| Removed | In a test | In code |
| --- | --- | --- |
| canAssign<T>()(v) | testType.canAssign<typeof v, T>(true) | v satisfies T |
| canAssign<T>(false)(v) | testType.canAssign<typeof v, T>(false) | |
| isType<T>(v) (one argument) | testType.canAssign<typeof v, T>(true) | v satisfies T |
| assertType<T>(v) (no validator) and its members | testType.* | v satisfies T, or assertType(v, validator) |
| isType.t / .f / .never / .equal | testType.true / .false / .never / .equal | |
Constant Types
KeyTypes
👽 alias: type of all keys.
PrimitiveTypes
👽 alias: all primitive types, including Function, symbol, and bigint.
ComposableTypes
👽 alias: Types that can contain custom properties. i.e. object, array, function.
NonComposableTypes
👽 alias: Types that cannot contain custom properties. i.e. not composable.
JSON Support
Full reference: JSON.
JsonPrimitive
👽 alias: primitive types valid in JSON
JsonObject
👽 alias: JSON object. A key may be absent but never undefined.
JsonArray
👽 alias: JSON array, readonly so tuples and as const data are accepted.
JsonTypes
👽 alias: any value JSON.parse can produce.
JsonCompatible<T>
🧰 type util: constrain with T extends JsonCompatible<T> to accept any JSON-safe value, including an interface.
The compiler error names the path of the part that is not JSON.
import type { JsonCompatible } from 'type-plus'
function save<T extends JsonCompatible<T>>(value: T) { ... }
interface Post { createdAt: Date }
save(post) // Type 'Date' is not assignable to type '"not JSON at $.createdAt"'
IsJson<T, $O>,IsNotJson<T, $O>
🎭 predicate: validate if T survives a JSON round trip.
Serialized<T, $O>,Deserialized<S>
🧰 type util: a string carrying the type of the value it was serialized from, and the type parsing it gives back.
Two lines of wrapper give JSON or flatted a typed round trip.
{ circular: true } tags flatted's format, so the two formats do not mix.
import type { Deserialized, JsonCompatible, Serialized } from 'type-plus'
const stringify = <T extends JsonCompatible<T>>(value: T) => JSON.stringify(value) as Serialized<T>
const parse = <S extends Serialized<any>>(text: S) => JSON.parse(text) as Deserialized<S>
const user = parse(stringify({ id: 1, tags: ['a'] })) // { id: number; tags: string[] }Type manipulation
ANotB<A, B>
🦴 utilities: get object with properties in A and not in B, including properties with a different value type.
BNotA<A, B>
🦴 utilities: flip of ANotB
as<T>(subject)
🦴 utilities: assert subject as T. Avoid ASI issues such as ;(x as T).abc
asAny(subject)
🦴 utilities: assert subject as any. Avoid ASI issue such as ;(x as any).abc
🗑️ removed in 8.0.0: EitherAnd — use EitherOrBoth instead.
EitherOrBoth<A, B, [C, D]>
🦴 utilities: combines 2 to 4 types as A | B | (A & B).
This is useful for combining options video.
🗑️ removed in 8.0.0: Except — use ObjectPlus.Omit instead.
ExcludePropType<T, U>
🦴 utilities: excludes type U from properties in T.
🗑️ removed in 8.0.0: KeysOfOptional — use OptionalKeys<T> for the optional keys, keyof T for
the key union.
KnownKeys<T>
🦴 utilities: extract known (defined) keys from type T.
LeftJoin<A, B>
🦴 utilities: left join A with B
NonNullable<T>(TypeScript built-in)
🦴 utilities: removes null and undefined from T. type-plus no longer ships its own
NonNull and NonUndefined; use the built-in, or IsNotNull / IsNotUndefined to test instead.
🗑️ removed in 8.0.0: the top-level Omit — use ObjectPlus.Omit instead.
ObjectPlus.Omit<T, K>
🦴 utilities: From T, pick a set of properties whose keys are not in the union K. This is the opposite of ObjectPlus.Pick<T, K>.
Unlike the built-in Omit, it distributes over unions and rejects a key no member of T has.
OptionalKeys<T>
🦴 utilities: gets keys of optional properties in T.
🗑️ removed in 8.0.0: the top-level Partial — use ObjectPlus.Partial instead.
🗑️ removed in 8.0.0: PartialExcept — use PartialOmit instead.
PartialOmit<T, U>
🦴 utilities: makes the properties not specified in U becomes optional.
PartialPick<T, U>
🦴 utilities: makes the properties specified in U becomes optional.
🗑️ removed in 8.0.0: the top-level Pick — use ObjectPlus.Pick instead.
ObjectPlus.Pick<T, K>
🦴 utilities: pick properties K from T. Unlike the built-in Pick, it distributes over unions.
RecursivePartial<T>
🦴 utilities: make type T optional recursively.
RecursiveRequired<T>
🦴 utilities: make type T required recursively.
ReplaceProperty<T, K, V>
🦴 utilities: replace property K in T with V.
🗑️ removed in 8.0.0: the top-level Required — use ObjectPlus.Required instead.
RequiredKeys<T>
🦴 utilities: gets keys of required properties in T.
RequiredPick<T, U>
🦴 utilities: makes the properties specified in U become required.
RequiredOmit<T, U>
🦴 utilities: makes the properties not specified in U become required.
💀 deprecated since 8.0.0: RequiredExcept — use RequiredOmit instead.
RecursiveIntersect<T, U>
🦴 utilities: intersect type U onto T recursively.
ValueOf<T>
🦴 utilities: type of the value of the properties of T.
Widen<T>
🦴 utilities: widen literal types.
PropType
💀 ...no helper type for this. Just do YourType['propName'].
Type Predicates
Type predicates are type alias that returns true or false.
They can be used to compose complex types.
HasKey<T, K>
🦴 utilities: predicate type checking T has key K.
IsAny<T>
🦴 utilities: T === any.
IsBoolean<T>
🦴 utilities: check for boolean, but not for true nor false.
IsDisjoint<A, B, $O>
🎭 predicate, 🔢 customizable: A and B share no key.
IsEmptyObject<T, $O>
🎭 predicate, 🔢 customizable: T is the empty object type {}.
IsLiteral<T>
🦴 utilities: is T a literal type (literal string or number).
Logical
🎭 predicate, 🔢 customizable: selects the $then branch when Condition is true, the $else branch otherwise.
🎭 predicate, 🔢 customizable: logical AND.
🎭 predicate, 🔢 customizable: logical OR.
🎭 predicate, 🔢 customizable: logical XOR.
🎭 predicate, 🔢 customizable: logical NOT.
Note that these types work correctly with the boolean type.
e.g.:
type R = And<boolean, true> // boolean
type R = Not<boolean> // booleanThere is a problem with generic distribution: https://github.com/microsoft/TypeScript/issues/41053 So you may encounter some weird behavior if your logic is complex.
Math
The math types in type-plus works with most numeric types.
It works with number and bigint, positive and negative number, including floating point numbers.
It will cast the type between number and bigint if needed.
Abs<N, $O>
🦴 utilities: Abs(N).
Max<A, B, $O>
🦴 utilities: max(A, B)
Min<A, B, $O>
🦴 utilities: min(A, B)
GreaterThan<A, B>
🦴 utilities: A > B.
GreaterThanOrEqual<A, B>
🦴 utilities: A >= B.
LessThan<A, B>
🦴 utilities: A < B.
LessThanOrEqual<A, B>
🦴 utilities: A <= B.
Add<A, B>
🦴 utilities: A + B.
Subtract<A, B>
🦴 utilities: A > B.
Increment<A>
🦴 utilities: alias of Add<A, 1>.
Decrement<A>
🦴 utilities: alias of Subtract<A, 1>.
Multiply<A, B
🦴 utilities: A * B.
Divide<A, B>
🦴 utilities: A / B, truncated toward zero to 16 fractional digits by default.
Quotient<A, B>
🦴 utilities: integer A / B, truncated toward zero.
Remainder<A, B>
🦴 utilities: A % B on integers.
Utility Functions
amend(subject)...
🦴 utilities: amend subject as union or intersect of T.
facade(subject, ...props)
🦴 utilities: create a facade of subject.
getField(subject, key, defaultValue)
🦴 utilities: get a field from a subject. Works against nullable and optional subject.
hasKey()
🦴 utilities: function of HasKey.
hasProperty(value, prop)
🦴 utilities: assert value has property prop. This will pick the correct union type.
🗑️ removed in 8.0.0: isConstructor — no replacement. It was not a failsafe test: it returned
true for any function that can be called with new. AnyConstructor stays.
isSystemError(code, err)
🦴 utilities: type guard err with NodeJS error code.
omit(obj, ...props)
🦴 utilities: omit properties from obj.
pick(obj, ...props)
🦴 utilities: pick properties from obj.
record<K, V>(value?)
🦴 utilities: create a Record<K, V> without extra object prototype.
record<R>(value?)
🦴 utilities: create a record R (e.g. { a: number }) without extra object prototype.
required(...)
🦴 utilities: merge up to three partial objects shallowly, left to right. A later undefined overwrites. From unpartial
requiredDeep(...)
🦴 utilities: merge up to three partial objects recursively, left to right. A later undefined keeps the earlier value, and a later array replaces the earlier one. From unpartial
split(target, ...splitters)
🦴 utilities: split one object into multiple objects.
stub<T>(value)
🦴 utilities: stub a particular type T. Imported from type-plus/testing.
stub.build<T>(init?)
🦴 utilities: build a stub for particular type T. Imported from type-plus/testing.
typeOverrideIncompatible<T>()
🦴 utilities: override only the incompatible portion between two types.
type A = {
foo: boolean,
bar: string,
baz: string
}
const overrider = typeOverrideIncompatible<A>()
const source = {
foo: 1,
bar: 'bar',
baz: 'baz'
}
// only the `foo` property is available to override.
overrider(source, { foo: !!source.foo })🗑️ removed in 8.0.0: unpartial() re-export — import it from the
unpartial package directly.
context()
🦴 utilities: a context builder.
This is useful to build context for functional programming.
It is a sync version of the AsyncContext from async-fp.
import { context } from 'type-plus'
// { a: 1, b: 2 }
const ctx = context({ a: 1 })
.extend(c => ({ b: c.a + 1 }))
.build()Nominal Types
The TypeScript type system is structural.
In some cases, we want to express a type with nominal behavior.
type-plus provides two kinds of nominal types: Brand and Flavor.
Brand<B, T>:
brand(type, subject?):
Branded nominal type is the stronger nominal type of the two. It disallows unbranded type assigned to it:
const a = brand('a', { a: 1 })
const b = { a: 1 }
a = b // errorsubject can be any type, from primitive to strings to objects.
brand(type):
If you do not provide subject, brand(type) will return a brand creator,
so that you can use it to create multiple branded values:
const nike = brand('nike')
const shirt = nike('shirt')
const socks = nike('socks')Flavor<F, T>:
flavor(type, subject?):
The key difference between Flavor and Brand is that
unflavored type can be assigned to Flavor:
let f = flavor('orange', 'soda')
f = 'mist' // okAlso, Brand of the same name can be assigned to Flavor,
but Flavor of the same name cannot be assigned to Brand.
nominalMatch(a, b):
🦴 utilities: compare if the two values are nominally equal.
Works with both Brand and Flavor.
const b1 = brand('x', 1)
const b2 = brand('y', 1)
nominalMatch(b1, b2) // falseFunctional Types
ChainFn<T>: T
🦴 utilities: chain function that returns the input type.
compose(...fns): F
🦴 utilities: compose functions
Attribution
Some code in this library is created by other people in the TypeScript community. I'm merely adding them in and maybe making some adjustments. Whenever possible, I add attribution to the person who created those codes in the file.
Useful Tips
Similar projects
expect-type: Compile-time tests for typeshotscript: Higher-order TypeScriptspec.ts: write tests for your types!ts-calc: compute with typescript type system, part ofhotscriptts-essentials: all essential TypeScript types in one place.ts-expect: Checks values in TypeScript match expectations.ts-toolbelt: TypeScript's largest utility library.type-fest: a collection of essential TypeScript types.type-zoo: a modest type lib usable today.typepark: a new type collection offering tuple manipulation andPipe.typelevel-ts: a type lib by @gcanti, author of several FP libraries in TS.typical: a playground of type-level operations for TypeScript.utility-types: collection of utility types, complementing TypeScript built-in mapped types and aliases.earl: Ergonomic, modern and type-safe assertion library for TypeScript
