type-fest
- Version 4.26.1
- Published
- 384 kB
- No dependencies
- (MIT OR CC0-1.0) license
Install
npm i type-fest
yarn add type-fest
pnpm add type-fest
Overview
A collection of essential TypeScript types
Index
Interfaces
Type Aliases
- AbstractConstructor
- And
- Arrayable
- ArrayIndices
- ArraySlice
- ArraySplice
- ArrayTail
- ArrayValues
- Asyncify
- AsyncReturnType
- CamelCase
- CamelCasedProperties
- CamelCasedPropertiesDeep
- Class
- ConditionalExcept
- ConditionalKeys
- ConditionalPick
- ConditionalPickDeep
- ConditionalPickDeepOptions
- Constructor
- DelimiterCase
- DelimiterCasedProperties
- DelimiterCasedPropertiesDeep
- DistributedOmit
- DistributedPick
- EmptyObject
- Entries
- Entry
- Exact
- Except
- FindGlobalInstanceType
- FindGlobalType
- Finite
- FixedLengthArray
- Float
- Get
- GetTagMetadata
- GlobalThis
- GreaterThan
- GreaterThanOrEqual
- HasOptionalKeys
- HasReadonlyKeys
- HasRequiredKeys
- HasWritableKeys
- IfAny
- IfEmptyObject
- IfNever
- IfNull
- IfUnknown
- Includes
- Integer
- IntRange
- InvariantOf
- IsAny
- IsBooleanLiteral
- IsEmptyObject
- IsEqual
- IsFloat
- IsInteger
- IsLiteral
- IsNegative
- IsNever
- IsNull
- IsNumericLiteral
- IsStringLiteral
- IsSymbolLiteral
- IsUnknown
- IterableElement
- Join
- JsonArray
- Jsonifiable
- Jsonify
- JsonObject
- JsonPrimitive
- JsonValue
- KebabCase
- KebabCasedProperties
- KebabCasedPropertiesDeep
- KeysOfUnion
- LastArrayElement
- LessThan
- LessThanOrEqual
- LiteralToPrimitive
- LiteralToPrimitiveDeep
- LiteralUnion
- Merge
- MergeDeep
- MergeDeepOptions
- MergeExclusive
- MultidimensionalArray
- MultidimensionalReadonlyArray
- Negative
- NegativeFloat
- NegativeInfinity
- NegativeInteger
- NonEmptyObject
- NonEmptyTuple
- NonNegative
- NonNegativeInteger
- ObservableLike
- Observer
- OmitDeep
- OmitIndexSignature
- OnComplete
- OnError
- OnNext
- Opaque
- OptionalKeysOf
- Or
- OverrideProperties
- PackageJson
- PartialDeep
- PartialDeepOptions
- PartialOnUndefinedDeep
- PartialOnUndefinedDeepOptions
- PascalCase
- PascalCasedProperties
- PascalCasedPropertiesDeep
- Paths
- PickDeep
- PickIndexSignature
- PositiveInfinity
- Primitive
- Promisable
- ReadonlyDeep
- ReadonlyKeysOf
- ReadonlyTuple
- Replace
- RequireAllOrNone
- RequireAtLeastOne
- RequiredDeep
- RequiredKeysOf
- RequireExactlyOne
- RequireOneOrNone
- Schema
- ScreamingSnakeCase
- SetFieldType
- SetNonNullable
- SetOptional
- SetParameterType
- SetReadonly
- SetRequired
- SetReturnType
- SharedUnionFieldsDeep
- Simplify
- SimplifyDeep
- SingleKeyObject
- SnakeCase
- SnakeCasedProperties
- SnakeCasedPropertiesDeep
- Split
- Spread
- Stringified
- StringKeyOf
- StringRepeat
- StringSlice
- StructuredCloneable
- Subtract
- Sum
- Tagged
- TaggedUnion
- Trim
- TsConfigJson
- TupleToUnion
- TypedArray
- UndefinedOnPartialDeep
- UnionToIntersection
- UnionToTuple
- UnknownArray
- UnknownRecord
- Unsubscribable
- UnwrapOpaque
- UnwrapTagged
- ValueOf
- Writable
- WritableDeep
- WritableKeysOf
Namespaces
Interfaces
interface AbstractClass
interface AbstractClass<T, Arguments extends unknown[] = any[]> extends AbstractConstructor<T, Arguments> {}
Matches an [
abstract class
](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes).Class
property prototype
prototype: Pick<T, keyof T>;
Type Aliases
type AbstractConstructor
type AbstractConstructor<T, Arguments extends unknown[] = any[]> = abstract new ( ...arguments_: Arguments) => T;
Matches an [
abstract class
](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor.Class
type And
type And<A extends boolean, B extends boolean> = [A, B][number] extends true ? true : true extends [IsEqual<A, false>, IsEqual<B, false>][number] ? false : never;
Returns a boolean for whether two given types are both true.
Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
Example 1
import type {And} from 'type-fest';And<true, true>;//=> trueAnd<true, false>;//=> falseSee Also
type Arrayable
type Arrayable<T> = T | readonly T[];
Create a type that represents either the value or an array of the value.
Example 1
import type {Arrayable} from 'type-fest';function bundle(input: string, output: Arrayable<string>) {const outputList = Array.isArray(output) ? output : [output];// …for (const output of outputList) {console.log(`write to: ${output}`);}}bundle('src/index.js', 'dist/index.js');bundle('src/index.js', ['dist/index.cjs', 'dist/index.mjs']);Array
See Also
Promisable
type ArrayIndices
type ArrayIndices<Element extends readonly unknown[]> = Exclude< Partial<Element>['length'], Element['length']>;
Provides valid indices for a constant array or tuple.
Use-case: This type is useful when working with constant arrays or tuples and you want to enforce type-safety for accessing elements by their indices.
Example 1
import type {ArrayIndices, ArrayValues} from 'type-fest';const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] as const;type Weekday = ArrayIndices<typeof weekdays>;type WeekdayName = ArrayValues<typeof weekdays>;const getWeekdayName = (day: Weekday): WeekdayName => weekdays[day];See Also
Array
type ArraySlice
type ArraySlice< Array_ extends readonly unknown[], Start extends number = never, End extends number = never> = And<IsEqual<Start, never>, IsEqual<End, never>> extends true ? Array_ : number extends Array_['length'] ? VariableLengthArraySliceHelper<Array_, Start, End> : ArraySliceHelper< Array_, IsEqual<Start, never> extends true ? 0 : Start, IsEqual<End, never> extends true ? Array_['length'] : End >;
Returns an array slice of a given range, just like
Array#slice()
.Example 1
import type {ArraySlice} from 'type-fest';type T0 = ArraySlice<[0, 1, 2, 3, 4]>;//=> [0, 1, 2, 3, 4]type T1 = ArraySlice<[0, 1, 2, 3, 4], 0, -1>;//=> [0, 1, 2, 3]type T2 = ArraySlice<[0, 1, 2, 3, 4], 1, -2>;//=> [1, 2]type T3 = ArraySlice<[0, 1, 2, 3, 4], -2, 4>;//=> [3]type T4 = ArraySlice<[0, 1, 2, 3, 4], -2, -1>;//=> [3]type T5 = ArraySlice<[0, 1, 2, 3, 4], 0, -999>;//=> []function arraySlice<const Array_ extends readonly unknown[],Start extends number = 0,End extends number = Array_['length'],>(array: Array_, start?: Start, end?: End) {return array.slice(start, end) as ArraySlice<Array_, Start, End>;}const slice = arraySlice([1, '2', {a: 3}, [4, 5]], 0, -1);typeof slice;//=> [1, '2', { readonly a: 3; }]slice[2].a;//=> 3// @ts-expect-error -- TS2493: Tuple type '[1, "2", {readonly a: 3}]' of length '3' has no element at index '3'.slice[3];Array
type ArraySplice
type ArraySplice< T extends UnknownArray, Start extends number, DeleteCount extends number, Items extends UnknownArray = []> = SplitArrayByIndex<T, Start> extends [ infer U extends UnknownArray, infer V extends UnknownArray] ? SplitArrayByIndex<V, DeleteCount> extends [ infer _Deleted extends UnknownArray, infer X extends UnknownArray ] ? [...U, ...Items, ...X] : never // Should never happen : never;
Creates a new array type by adding or removing elements at a specified index range in the original array.
Use-case: Replace or insert items in an array type.
Like [
Array#splice()
](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) but for types.Example 1
type SomeMonths0 = ['January', 'April', 'June'];type Mouths0 = ArraySplice<SomeMonths0, 1, 0, ['Feb', 'March']>;//=> type Mouths0 = ['January', 'Feb', 'March', 'April', 'June'];type SomeMonths1 = ['January', 'April', 'June'];type Mouths1 = ArraySplice<SomeMonths1, 1, 1>;//=> type Mouths1 = ['January', 'June'];type SomeMonths2 = ['January', 'Foo', 'April'];type Mouths2 = ArraySplice<SomeMonths2, 1, 1, ['Feb', 'March']>;//=> type Mouths2 = ['January', 'Feb', 'March', 'April'];Array
type ArrayTail
type ArrayTail<TArray extends UnknownArrayOrTuple> = TArray extends readonly [ unknown, ...infer Tail] ? Tail : [];
Extracts the type of an array or tuple minus the first element.
Example 1
import type {ArrayTail} from 'type-fest';declare const curry: <Arguments extends unknown[], Return>(function_: (...arguments_: Arguments) => Return,...arguments_: ArrayTail<Arguments>) => (...arguments_: ArrayTail<Arguments>) => Return;const add = (a: number, b: number) => a + b;const add3 = curry(add, 3);add3(4);//=> 7Array
type ArrayValues
type ArrayValues<T extends readonly unknown[]> = T[number];
Provides all values for a constant array or tuple.
Use-case: This type is useful when working with constant arrays or tuples and you want to enforce type-safety with their values.
Example 1
import type {ArrayValues, ArrayIndices} from 'type-fest';const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] as const;type WeekdayName = ArrayValues<typeof weekdays>;type Weekday = ArrayIndices<typeof weekdays>;const getWeekdayName = (day: Weekday): WeekdayName => weekdays[day];See Also
Array
type Asyncify
type Asyncify<Function_ extends (...arguments_: any[]) => any> = SetReturnType< Function_, Promise<Awaited<ReturnType<Function_>>>>;
Create an async version of the given function type, by boxing the return type in
Promise
while keeping the same parameter types.Use-case: You have two functions, one synchronous and one asynchronous that do the same thing. Instead of having to duplicate the type definition, you can use
Asyncify
to reuse the synchronous type.Example 1
import type {Asyncify} from 'type-fest';// Synchronous function.function getFooSync(someArg: SomeType): Foo {// …}type AsyncifiedFooGetter = Asyncify<typeof getFooSync>;//=> type AsyncifiedFooGetter = (someArg: SomeType) => Promise<Foo>;// Same as `getFooSync` but asynchronous.const getFooAsync: AsyncifiedFooGetter = (someArg) => {// TypeScript now knows that `someArg` is `SomeType` automatically.// It also knows that this function must return `Promise<Foo>`.// If you have `@typescript-eslint/promise-function-async` linter rule enabled, it will even report that "Functions that return promises must be async.".// …}Async
type AsyncReturnType
type AsyncReturnType<Target extends AsyncFunction> = Awaited<ReturnType<Target>>;
Unwrap the return type of a function that returns a
Promise
.There has been [discussion](https://github.com/microsoft/TypeScript/pull/35998) about implementing this type in TypeScript.
Example 1
import type {AsyncReturnType} from 'type-fest';import {asyncFunction} from 'api';// This type resolves to the unwrapped return type of `asyncFunction`.type Value = AsyncReturnType<typeof asyncFunction>;async function doSomething(value: Value) {}asyncFunction().then(value => doSomething(value));Async
type CamelCase
type CamelCase< Type, Options extends CamelCaseOptions = { preserveConsecutiveUppercase: true }> = Type extends string ? string extends Type ? Type : Uncapitalize< CamelCaseFromArray< SplitWords<Type extends Uppercase<Type> ? Lowercase<Type> : Type>, Options > > : Type;
Convert a string literal to camel-case.
This can be useful when, for example, converting some kebab-cased command-line flags or a snake-cased database result.
By default, consecutive uppercase letter are preserved. See option to change this behaviour.
Example 1
import type {CamelCase} from 'type-fest';// Simpleconst someVariable: CamelCase<'foo-bar'> = 'fooBar';// Advancedtype CamelCasedProperties<T> = {[K in keyof T as CamelCase<K>]: T[K]};interface RawOptions {'dry-run': boolean;'full_family_name': string;foo: number;BAR: string;QUZ_QUX: number;'OTHER-FIELD': boolean;}const dbResult: CamelCasedProperties<RawOptions> = {dryRun: true,fullFamilyName: 'bar.js',foo: 123,bar: 'foo',quzQux: 6,otherField: false};Change case Template literal
type CamelCasedProperties
type CamelCasedProperties< Value, Options extends CamelCaseOptions = { preserveConsecutiveUppercase: true }> = Value extends Function ? Value : Value extends Array<infer U> ? Value : { [K in keyof Value as CamelCase<K, Options>]: Value[K]; };
Convert object properties to camel case but not recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {CamelCasedProperties} from 'type-fest';interface User {UserId: number;UserName: string;}const result: CamelCasedProperties<User> = {userId: 1,userName: 'Tom',};Change case Template literal Object
See Also
CamelCasedPropertiesDeep
CamelCase
type CamelCasedPropertiesDeep
type CamelCasedPropertiesDeep< Value, Options extends CamelCaseOptions = { preserveConsecutiveUppercase: true }> = Value extends NonRecursiveType ? Value : Value extends UnknownArray ? CamelCasedPropertiesArrayDeep<Value> : Value extends Set<infer U> ? Set<CamelCasedPropertiesDeep<U, Options>> : { [K in keyof Value as CamelCase<K, Options>]: CamelCasedPropertiesDeep< Value[K], Options >; };
Convert object properties to camel case recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {CamelCasedPropertiesDeep} from 'type-fest';interface User {UserId: number;UserName: string;}interface UserWithFriends {UserInfo: User;UserFriends: User[];}const result: CamelCasedPropertiesDeep<UserWithFriends> = {userInfo: {userId: 1,userName: 'Tom',},userFriends: [{userId: 2,userName: 'Jerry',},{userId: 3,userName: 'Spike',},],};Change case Template literal Object
See Also
CamelCasedProperties
CamelCase
type Class
type Class<T, Arguments extends unknown[] = any[]> = { prototype: Pick<T, keyof T>; new (...arguments_: Arguments): T;};
Matches a [
class
](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).Class
type ConditionalExcept
type ConditionalExcept<Base, Condition> = Except< Base, ConditionalKeys<Base, Condition>>;
Exclude keys from a shape that matches the given
Condition
.This is useful when you want to create a new type with a specific set of keys from a shape. For example, you might want to exclude all the primitive properties from a class and form a new shape containing everything but the primitive properties.
Example 1
import type {Primitive, ConditionalExcept} from 'type-fest';class Awesome {name: string;successes: number;failures: bigint;run() {}}type ExceptPrimitivesFromAwesome = ConditionalExcept<Awesome, Primitive>;//=> {run: () => void}Example 2
import type {ConditionalExcept} from 'type-fest';interface Example {a: string;b: string | number;c: () => void;d: {};}type NonStringKeysOnly = ConditionalExcept<Example, string>;//=> {b: string | number; c: () => void; d: {}}Object
type ConditionalKeys
type ConditionalKeys<Base, Condition> = { // Map through all the keys of the given base type. [Key in keyof Base]-?: // Pick only keys with types extending the given `Condition` type. Base[Key] extends Condition ? // Retain this key // If the value for the key extends never, only include it if `Condition` also extends never IfNever<Base[Key], IfNever<Condition, Key, never>, Key> : // Discard this key since the condition fails. never; // Convert the produced object into a union type of the keys which passed the conditional test.}[keyof Base];
Extract the keys from a type where the value type of the key extends the given
Condition
.Internally this is used for the
ConditionalPick
andConditionalExcept
types.Example 1
import type {ConditionalKeys} from 'type-fest';interface Example {a: string;b: string | number;c?: string;d: {};}type StringKeysOnly = ConditionalKeys<Example, string>;//=> 'a'To support partial types, make sure your
Condition
is a union of undefined (for example,string | undefined
) as demonstrated below.Example 2
import type {ConditionalKeys} from 'type-fest';type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;//=> 'a' | 'c'Object
type ConditionalPick
type ConditionalPick<Base, Condition> = Pick<Base, ConditionalKeys<Base, Condition>>;
Pick keys from the shape that matches the given
Condition
.This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type.
Example 1
import type {Primitive, ConditionalPick} from 'type-fest';class Awesome {name: string;successes: number;failures: bigint;run() {}}type PickPrimitivesFromAwesome = ConditionalPick<Awesome, Primitive>;//=> {name: string; successes: number; failures: bigint}Example 2
import type {ConditionalPick} from 'type-fest';interface Example {a: string;b: string | number;c: () => void;d: {};}type StringKeysOnly = ConditionalPick<Example, string>;//=> {a: string}Object
type ConditionalPickDeep
type ConditionalPickDeep< Type, Condition, Options extends ConditionalPickDeepOptions = {}> = ConditionalSimplifyDeep< ConditionalExcept< { [Key in keyof Type]: AssertCondition< Type[Key], Condition, Options > extends true ? Type[Key] : IsPlainObject<Type[Key]> extends true ? ConditionalPickDeep<Type[Key], Condition, Options> : typeof conditionalPickDeepSymbol; }, (typeof conditionalPickDeepSymbol | undefined) | EmptyObject >, never, UnknownRecord>;
Pick keys recursively from the shape that matches the given condition.
Example 1
import type {ConditionalPickDeep} from 'type-fest';interface Example {a: string;b: string | boolean;c: {d: string;e: {f?: string;g?: boolean;h: string | boolean;i: boolean | bigint;};j: boolean;};}type StringPick = ConditionalPickDeep<Example, string>;//=> {a: string; c: {d: string}}type StringPickOptional = ConditionalPickDeep<Example, string | undefined>;//=> {a: string; c: {d: string; e: {f?: string}}}type StringPickOptionalOnly = ConditionalPickDeep<Example, string | undefined, {condition: 'equality'}>;//=> {c: {e: {f?: string}}}type BooleanPick = ConditionalPickDeep<Example, boolean | undefined>;//=> {c: {e: {g?: boolean}; j: boolean}}type NumberPick = ConditionalPickDeep<Example, number>;//=> {}type StringOrBooleanPick = ConditionalPickDeep<Example, string | boolean>;//=> {// a: string;// b: string | boolean;// c: {// d: string;// e: {// h: string | boolean// };// j: boolean;// };// }type StringOrBooleanPickOnly = ConditionalPickDeep<Example, string | boolean, {condition: 'equality'}>;//=> {b: string | boolean; c: {e: {h: string | boolean}}}Object
See Also
ConditionalPick
type ConditionalPickDeepOptions
type ConditionalPickDeepOptions = { /** The condition assertion mode.
@default 'extends' */ condition?: 'extends' | 'equality';};
ConditionalPickDeep options.
See Also
ConditionalPickDeep
type Constructor
type Constructor<T, Arguments extends unknown[] = any[]> = new ( ...arguments_: Arguments) => T;
Matches a [
class
constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).Class
type DelimiterCase
type DelimiterCase<Value, Delimiter extends string> = string extends Value ? Value : Value extends string ? StringArrayToDelimiterCase< SplitIncludingDelimiters<Value, WordSeparators | UpperCaseCharacters>, true, WordSeparators, UpperCaseCharacters, Delimiter > : Value;
Convert a string literal to a custom string delimiter casing.
This can be useful when, for example, converting a camel-cased object property to an oddly cased one.
Example 1
import type {DelimiterCase} from 'type-fest';// Simpleconst someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar';// Advancedtype OddlyCasedProperties<T> = {[K in keyof T as DelimiterCase<K, '#'>]: T[K]};interface SomeOptions {dryRun: boolean;includeFile: string;foo: number;}const rawCliOptions: OddlyCasedProperties<SomeOptions> = {'dry#run': true,'include#file': 'bar.js',foo: 123};Change case Template literal
See Also
KebabCase
SnakeCase
type DelimiterCasedProperties
type DelimiterCasedProperties< Value, Delimiter extends string> = Value extends Function ? Value : Value extends Array<infer U> ? Value : { [K in keyof Value as DelimiterCase<K, Delimiter>]: Value[K] };
Convert object properties to delimiter case but not recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {DelimiterCasedProperties} from 'type-fest';interface User {userId: number;userName: string;}const result: DelimiterCasedProperties<User, '-'> = {'user-id': 1,'user-name': 'Tom',};Change case Template literal Object
See Also
DelimiterCase
DelimiterCasedPropertiesDeep
type DelimiterCasedPropertiesDeep
type DelimiterCasedPropertiesDeep< Value, Delimiter extends string> = Value extends NonRecursiveType ? Value : Value extends UnknownArray ? DelimiterCasedPropertiesArrayDeep<Value, Delimiter> : Value extends Set<infer U> ? Set<DelimiterCasedPropertiesDeep<U, Delimiter>> : { [K in keyof Value as DelimiterCase< K, Delimiter >]: DelimiterCasedPropertiesDeep<Value[K], Delimiter>; };
Convert object properties to delimiter case recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {DelimiterCasedPropertiesDeep} from 'type-fest';interface User {userId: number;userName: string;}interface UserWithFriends {userInfo: User;userFriends: User[];}const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {'user-info': {'user-id': 1,'user-name': 'Tom',},'user-friends': [{'user-id': 2,'user-name': 'Jerry',},{'user-id': 3,'user-name': 'Spike',},],};Change case Template literal Object
See Also
DelimiterCase
DelimiterCasedProperties
type DistributedOmit
type DistributedOmit< ObjectType, KeyType extends KeysOfUnion<ObjectType>> = ObjectType extends unknown ? Omit<ObjectType, KeyType> : never;
Omits keys from a type, distributing the operation over a union.
TypeScript's
Omit
doesn't distribute over unions, leading to the erasure of unique properties from union members when omitting keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Omit. Essentially, usingOmit
on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that.Example:
type A = {discriminant: 'A';foo: string;a: number;};type B = {discriminant: 'B';foo: string;b: string;};type Union = A | B;type OmittedUnion = Omit<Union, 'foo'>;//=> {discriminant: 'A' | 'B'}const omittedUnion: OmittedUnion = createOmittedUnion();if (omittedUnion.discriminant === 'A') {// We would like to narrow `omittedUnion`'s type// to `A` here, but we can't because `Omit`// doesn't distribute over unions.omittedUnion.a;//=> Error: `a` is not a property of `{discriminant: 'A' | 'B'}`}While
Except
solves this problem, it restricts the keys you can omit to the ones that are present in **ALL** union members, whereDistributedOmit
allows you to omit keys that are present in **ANY** union member.Example 1
type A = {discriminant: 'A';foo: string;a: number;};type B = {discriminant: 'B';foo: string;bar: string;b: string;};type C = {discriminant: 'C';bar: string;c: boolean;};// Notice that `foo` exists in `A` and `B`, but not in `C`, and// `bar` exists in `B` and `C`, but not in `A`.type Union = A | B | C;type OmittedUnion = DistributedOmit<Union, 'foo' | 'bar'>;const omittedUnion: OmittedUnion = createOmittedUnion();if (omittedUnion.discriminant === 'A') {omittedUnion.a;//=> OKomittedUnion.foo;//=> Error: `foo` is not a property of `{discriminant: 'A'; a: string}`omittedUnion.bar;//=> Error: `bar` is not a property of `{discriminant: 'A'; a: string}`}Object
type DistributedPick
type DistributedPick< ObjectType, KeyType extends KeysOfUnion<ObjectType>> = ObjectType extends unknown ? Pick<ObjectType, Extract<KeyType, keyof ObjectType>> : never;
Pick keys from a type, distributing the operation over a union.
TypeScript's
Pick
doesn't distribute over unions, leading to the erasure of unique properties from union members when picking keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Pick. Essentially, usingPick
on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that.Example:
type A = {discriminant: 'A';foo: {bar: string;};};type B = {discriminant: 'B';foo: {baz: string;};};type Union = A | B;type PickedUnion = Pick<Union, 'discriminant' | 'foo'>;//=> {discriminant: 'A' | 'B', foo: {bar: string} | {baz: string}}const pickedUnion: PickedUnion = createPickedUnion();if (pickedUnion.discriminant === 'A') {// We would like to narrow `pickedUnion`'s type// to `A` here, but we can't because `Pick`// doesn't distribute over unions.pickedUnion.foo.bar;//=> Error: Property 'bar' does not exist on type '{bar: string} | {baz: string}'.}Example 1
type A = {discriminant: 'A';foo: {bar: string;};extraneous: boolean;};type B = {discriminant: 'B';foo: {baz: string;};extraneous: boolean;};// Notice that `foo.bar` exists in `A` but not in `B`.type Union = A | B;type PickedUnion = DistributedPick<Union, 'discriminant' | 'foo'>;const pickedUnion: PickedUnion = createPickedUnion();if (pickedUnion.discriminant === 'A') {pickedUnion.foo.bar;//=> OKpickedUnion.extraneous;//=> Error: Property `extraneous` does not exist on type `Pick<A, 'discriminant' | 'foo'>`.pickedUnion.foo.baz;//=> Error: `bar` is not a property of `{discriminant: 'A'; a: string}`.}Object
type EmptyObject
type EmptyObject = { [emptyObjectSymbol]?: never };
Represents a strictly empty plain object, the
{}
value.When you annotate something as the type
{}
, it can be anything exceptnull
andundefined
. This means that you cannot use{}
to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)).Example 1
import type {EmptyObject} from 'type-fest';// The following illustrates the problem with `{}`.const foo1: {} = {}; // Passconst foo2: {} = []; // Passconst foo3: {} = 42; // Passconst foo4: {} = {a: 1}; // Pass// With `EmptyObject` only the first case is valid.const bar1: EmptyObject = {}; // Passconst bar2: EmptyObject = 42; // Failconst bar3: EmptyObject = []; // Failconst bar4: EmptyObject = {a: 1}; // FailUnfortunately,
Record<string, never>
,Record<keyof any, never>
andRecord<never, never>
do not work. See .Object
type Entries
type Entries<BaseType> = BaseType extends Map<unknown, unknown> ? MapEntries<BaseType> : BaseType extends Set<unknown> ? SetEntries<BaseType> : BaseType extends readonly unknown[] ? ArrayEntries<BaseType> : BaseType extends object ? ObjectEntries<BaseType> : never;
Many collections have an
entries
method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. TheEntries
type will return the type of that collection's entries.For example the `Object`, `Map`, `Array`, and `Set` collections all have this method. Note that
WeakMap
andWeakSet
do not have this method since their entries are not enumerable.Example 1
import type {Entries} from 'type-fest';interface Example {someKey: number;}const manipulatesEntries = (examples: Entries<Example>) => examples.map(example => [// Does some arbitrary processing on the key (with type information available)example[0].toUpperCase(),// Does some arbitrary processing on the value (with type information available)example[1].toFixed()]);const example: Example = {someKey: 1};const entries = Object.entries(example) as Entries<Example>;const output = manipulatesEntries(entries);// Objectsconst objectExample = {a: 1};const objectEntries: Entries<typeof objectExample> = [['a', 1]];// Arraysconst arrayExample = ['a', 1];const arrayEntries: Entries<typeof arrayExample> = [[0, 'a'], [1, 1]];// Mapsconst mapExample = new Map([['a', 1]]);const mapEntries: Entries<typeof map> = [['a', 1]];// Setsconst setExample = new Set(['a', 1]);const setEntries: Entries<typeof setExample> = [['a', 'a'], [1, 1]];Object Map Set Array
See Also
Entry
if you want to just access the type of a single entry.
type Entry
type Entry<BaseType> = BaseType extends Map<unknown, unknown> ? MapEntry<BaseType> : BaseType extends Set<unknown> ? SetEntry<BaseType> : BaseType extends readonly unknown[] ? ArrayEntry<BaseType> : BaseType extends object ? ObjectEntry<BaseType> : never;
Many collections have an
entries
method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. TheEntry
type will return the type of that collection's entry.For example the `Object`, `Map`, `Array`, and `Set` collections all have this method. Note that
WeakMap
andWeakSet
do not have this method since their entries are not enumerable.Example 1
import type {Entry} from 'type-fest';interface Example {someKey: number;}const manipulatesEntry = (example: Entry<Example>) => [// Does some arbitrary processing on the key (with type information available)example[0].toUpperCase(),// Does some arbitrary processing on the value (with type information available)example[1].toFixed(),];const example: Example = {someKey: 1};const entry = Object.entries(example)[0] as Entry<Example>;const output = manipulatesEntry(entry);// Objectsconst objectExample = {a: 1};const objectEntry: Entry<typeof objectExample> = ['a', 1];// Arraysconst arrayExample = ['a', 1];const arrayEntryString: Entry<typeof arrayExample> = [0, 'a'];const arrayEntryNumber: Entry<typeof arrayExample> = [1, 1];// Mapsconst mapExample = new Map([['a', 1]]);const mapEntry: Entry<typeof mapExample> = ['a', 1];// Setsconst setExample = new Set(['a', 1]);const setEntryString: Entry<typeof setExample> = ['a', 'a'];const setEntryNumber: Entry<typeof setExample> = [1, 1];Object Map Array Set
See Also
Entries
if you want to just access the type of the array of entries (which is the return of the.entries()
method).
type Exact
type Exact<ParameterType, InputType> = // Before distributing, check if the two types are equal and if so, return the parameter type immediately IsEqual<ParameterType, InputType> extends true ? ParameterType : // If the parameter is a primitive, return it as is immediately to avoid it being converted to a complex type ParameterType extends Primitive ? ParameterType : // If the parameter is an unknown, return it as is immediately to avoid it being converted to a complex type IsUnknown<ParameterType> extends true ? unknown : // If the parameter is a Function, return it as is because this type is not capable of handling function, leave it to TypeScript ParameterType extends Function ? ParameterType : // Convert union of array to array of union: A[] & B[] => (A & B)[] ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>> : // In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray. ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>> : ExactObject<ParameterType, InputType>;
Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared.
This is useful for function type-guarding to reject arguments with excess properties. Due to the nature of TypeScript, it does not complain if excess properties are provided unless the provided value is an object literal.
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/12936) if you want to have this type as a built-in in TypeScript.*
Example 1
type OnlyAcceptName = {name: string};function onlyAcceptName(arguments_: OnlyAcceptName) {}// TypeScript complains about excess properties when an object literal is provided.onlyAcceptName({name: 'name', id: 1});//=> `id` is excess// TypeScript does not complain about excess properties when the provided value is a variable (not an object literal).const invalidInput = {name: 'name', id: 1};onlyAcceptName(invalidInput); // No errorsHaving
Exact
allows TypeScript to reject excess properties.Example 2
import {Exact} from 'type-fest';type OnlyAcceptName = {name: string};function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(arguments_: T) {}const invalidInput = {name: 'name', id: 1};onlyAcceptNameImproved(invalidInput); // Compilation error[Read more](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined)
Utilities
type Except
type Except< ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = { requireExactProps: false }> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];} & (Options['requireExactProps'] extends true ? Partial<Record<KeysType, never>> : {});
Create a type from an object type without certain keys.
We recommend setting the
requireExactProps
option totrue
.This type is a stricter version of [
Omit
](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). TheOmit
type does not restrict the omitted keys to be keys present on the given type, whileExcept
does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically.This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)).
Example 1
import type {Except} from 'type-fest';type Foo = {a: number;b: string;};type FooWithoutA = Except<Foo, 'a'>;//=> {b: string}const fooWithoutA: FooWithoutA = {a: 1, b: '2'};//=> errors: 'a' does not exist in type '{ b: string; }'type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>;//=> {a: number} & Partial<Record<"b", never>>const fooWithoutB: FooWithoutB = {a: 1, b: '2'};//=> errors at 'b': Type 'string' is not assignable to type 'undefined'.Object
type FindGlobalInstanceType
type FindGlobalInstanceType<Name extends string> = Name extends string ? typeof globalThis extends Record< Name, abstract new (...arguments: any[]) => infer T > ? T : never : never;
Tries to find one or more types from their globally-defined constructors.
Use-case: Conditionally referencing DOM types only when the DOM library present.
Limitations:* Due to peculiarities with the behavior of
globalThis
, "globally defined" has a narrow definition in this case. Declaring a class in adeclare global
block won't work, instead you must declare its type using an interface and declare its constructor as avar
(*not*let
/const
) inside thedeclare global
block.Example 1
import type {FindGlobalInstanceType} from 'type-fest';class Point {constructor(public x: number, public y: number) {}}type PointLike = Point | FindGlobalInstanceType<'DOMPoint'>;Example 2
import type {FindGlobalInstanceType} from 'type-fest';declare global {// Class syntax won't add the key to `globalThis`class Foo {}// interface + constructor style worksinterface Bar {}var Bar: new () => Bar; // Not let or const}type FindFoo = FindGlobalInstanceType<'Foo'>; // Doesn't worktype FindBar = FindGlobalInstanceType<'Bar'>; // WorksUtilities
type FindGlobalType
type FindGlobalType<Name extends string> = typeof globalThis extends Record< Name, infer T> ? T : never;
Tries to find the type of a global with the given name.
Limitations: Due to peculiarities with the behavior of
globalThis
, "globally defined" only includesvar
declarations indeclare global
blocks, notlet
orconst
declarations.Example 1
import type {FindGlobalType} from 'type-fest';declare global {const foo: number; // let and const don't workvar bar: string; // var works}type FooType = FindGlobalType<'foo'> //=> never (let/const don't work)type BarType = FindGlobalType<'bar'> //=> stringtype OtherType = FindGlobalType<'other'> //=> never (no global named 'other')Utilities
type Finite
type Finite<T extends number> = T extends PositiveInfinity | NegativeInfinity ? never : T;
A finite
number
. You can't pass abigint
as they are already guaranteed to be finite.Use-case: Validating and documenting parameters.
Note: This can't detect
NaN
, please upvote [this issue](https://github.com/microsoft/TypeScript/issues/28682) if you want to have this type as a built-in in TypeScript.Example 1
import type {Finite} from 'type-fest';declare function setScore<T extends number>(length: Finite<T>): void;Numeric
type FixedLengthArray
type FixedLengthArray< Element, Length extends number, ArrayPrototype = [Element, ...Element[]]> = Pick<ArrayPrototype, Exclude<keyof ArrayPrototype, ArrayLengthMutationKeys>> & { [index: number]: Element; [Symbol.iterator]: () => IterableIterator<Element>; readonly length: Length;};
Create a type that represents an array of the given type and length. The array's length and the
Array
prototype methods that manipulate its length are excluded in the resulting type.Please participate in [this issue](https://github.com/microsoft/TypeScript/issues/26223) if you want to have a similar type built into TypeScript.
Use-cases: - Declaring fixed-length tuples or arrays with a large number of items. - Creating a range union (for example,
0 | 1 | 2 | 3 | 4
from the keys of such a type) without having to resort to recursive types. - Creating an array of coordinates with a static length, for example, length of 3 for a 3D vector.Note: This type does not prevent out-of-bounds access. Prefer
ReadonlyTuple
unless you need mutability.Example 1
import type {FixedLengthArray} from 'type-fest';type FencingTeam = FixedLengthArray<string, 3>;const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert'];const homeFencingTeam: FencingTeam = ['George', 'John'];//=> error TS2322: Type string[] is not assignable to type 'FencingTeam'guestFencingTeam.push('Sam');//=> error TS2339: Property 'push' does not exist on type 'FencingTeam'Array
See Also
ReadonlyTuple
type Float
type Float<T> = T extends unknown // To distributive type ? IsFloat<T> extends true ? T : never : never;
A
number
that is not an integer.Use-case: Validating and documenting parameters.
It does not accept
Infinity
.Example 1
import type {Float} from 'type-fest';declare function setPercentage<T extends number>(length: Float<T>): void;See Also
Integer
Numeric
type Get
type Get< BaseType, Path extends | readonly string[] | LiteralStringUnion< ToString< | Paths<BaseType, { bracketNotation: false }> | Paths<BaseType, { bracketNotation: true }> > >, Options extends GetOptions = {}> = GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
Get a deeply-nested property from an object using a key path, like Lodash's
.get()
function.Use-case: Retrieve a property from deep inside an API response or some other complex object.
Example 1
import type {Get} from 'type-fest';import * as lodash from 'lodash';const get = <BaseType, Path extends string | readonly string[]>(object: BaseType, path: Path): Get<BaseType, Path> =>lodash.get(object, path);interface ApiResponse {hits: {hits: Array<{_id: string_source: {name: Array<{given: string[]family: string}>birthDate: string}}>}}const getName = (apiResponse: ApiResponse) =>get(apiResponse, 'hits.hits[0]._source.name');//=> Array<{given: string[]; family: string}> | undefined// Path also supports a readonly array of stringsconst getNameWithPathArray = (apiResponse: ApiResponse) =>get(apiResponse, ['hits','hits', '0', '_source', 'name'] as const);//=> Array<{given: string[]; family: string}> | undefined// Non-strict mode:Get<string[], '3', {strict: false}> //=> stringGet<Record<string, string>, 'foo', {strict: true}> // => stringObject Array Template literal
type GetTagMetadata
type GetTagMetadata< Type extends Tag<TagName, unknown>, TagName extends PropertyKey> = Type[typeof tag][TagName];
Given a type and a tag name, returns the metadata associated with that tag on that type.
In the example below, one could use
Tagged<string, 'JSON'>
to represent "a string that is valid JSON". That type might be useful -- for instance, it communicates that the value can be safely passed toJSON.parse
without it throwing an exception. However, it doesn't indicate what type of value will be produced on parse (which is sometimes known).JsonOf<T>
solves this; it represents "a string that is valid JSON and that, if parsed, would produce a value of type T". The type T is held in the metadata associated with the'JSON'
tag.This article explains more about [how tag metadata works and when it can be useful](https://medium.com/@ethanresnick/advanced-typescript-tagged-types-improved-with-type-level-metadata-5072fc125fcf).
Example 1
import type {Tagged} from 'type-fest';type JsonOf<T> = Tagged<string, 'JSON', T>;function stringify<T>(it: T) {return JSON.stringify(it) as JsonOf<T>;}function parse<T extends JsonOf<unknown>>(it: T) {return JSON.parse(it) as GetTagMetadata<T, 'JSON'>;}const x = stringify({ hello: 'world' });const parsed = parse(x); // The type of `parsed` is { hello: string }Type
type GlobalThis
type GlobalThis = typeof globalThis;
Declare locally scoped properties on
globalThis
.When defining a global variable in a declaration file is inappropriate, it can be helpful to define a
type
orinterface
(sayExtraGlobals
) with the global variable and then castglobalThis
via code likeglobalThis as unknown as ExtraGlobals
.Instead of casting through
unknown
, you can update yourtype
orinterface
to extendGlobalThis
and then directly castglobalThis
.Example 1
import type {GlobalThis} from 'type-fest';type ExtraGlobals = GlobalThis & {readonly GLOBAL_TOKEN: string;};(globalThis as ExtraGlobals).GLOBAL_TOKEN;Type
type GreaterThan
type GreaterThan<A extends number, B extends number> = number extends A | B ? never : [ IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>, IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity> ] extends infer R extends [boolean, boolean, boolean, boolean] ? Or< And<IsEqual<R[0], true>, IsEqual<R[2], false>>, And<IsEqual<R[3], true>, IsEqual<R[1], false>> > extends true ? true : Or< And<IsEqual<R[1], true>, IsEqual<R[3], false>>, And<IsEqual<R[2], true>, IsEqual<R[0], false>> > extends true ? false : true extends R[number] ? false : [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean] ? [true, false] extends R ? false : [false, true] extends R ? true : [false, false] extends R ? PositiveNumericStringGt<`${A}`, `${B}`> : PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`> : never : never;
Returns a boolean for whether a given number is greater than another number.
Example 1
import type {GreaterThan} from 'type-fest';GreaterThan<1, -5>;//=> trueGreaterThan<1, 1>;//=> falseGreaterThan<1, 5>;//=> false
type GreaterThanOrEqual
type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B ? never : A extends B ? true : GreaterThan<A, B>;
Returns a boolean for whether a given number is greater than or equal to another number.
Example 1
import type {GreaterThanOrEqual} from 'type-fest';GreaterThanOrEqual<1, -5>;//=> trueGreaterThanOrEqual<1, 1>;//=> trueGreaterThanOrEqual<1, 5>;//=> false
type HasOptionalKeys
type HasOptionalKeys<BaseType extends object> = OptionalKeysOf<BaseType> extends never ? false : true;
Creates a type that represents
true
orfalse
depending on whether the given type has any optional fields.This is useful when you want to create an API whose behavior depends on the presence or absence of optional fields.
Example 1
import type {HasOptionalKeys, OptionalKeysOf} from 'type-fest';type UpdateService<Entity extends object> = {removeField: HasOptionalKeys<Entity> extends true? (field: OptionalKeysOf<Entity>) => Promise<void>: never}Utilities
type HasReadonlyKeys
type HasReadonlyKeys<BaseType extends object> = ReadonlyKeysOf<BaseType> extends never ? false : true;
Creates a type that represents
true
orfalse
depending on whether the given type has any readonly fields.This is useful when you want to create an API whose behavior depends on the presence or absence of readonly fields.
Example 1
import type {HasReadonlyKeys, ReadonlyKeysOf} from 'type-fest';type UpdateService<Entity extends object> = {removeField: HasReadonlyKeys<Entity> extends true? (field: ReadonlyKeysOf<Entity>) => Promise<void>: never}Utilities
type HasRequiredKeys
type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
Creates a type that represents
true
orfalse
depending on whether the given type has any required fields.This is useful when you want to create an API whose behavior depends on the presence or absence of required fields.
Example 1
import type {HasRequiredKeys} from 'type-fest';type GeneratorOptions<Template extends object> = {prop1: number;prop2: string;} & (HasRequiredKeys<Template> extends true? {template: Template}: {template?: Template});interface Template1 {optionalSubParam?: string;}interface Template2 {requiredSubParam: string;}type Options1 = GeneratorOptions<Template1>;type Options2 = GeneratorOptions<Template2>;const optA: Options1 = {prop1: 0,prop2: 'hi'};const optB: Options1 = {prop1: 0,prop2: 'hi',template: {}};const optC: Options1 = {prop1: 0,prop2: 'hi',template: {optionalSubParam: 'optional value'}};const optD: Options2 = {prop1: 0,prop2: 'hi',template: {requiredSubParam: 'required value'}};Utilities
type HasWritableKeys
type HasWritableKeys<BaseType extends object> = WritableKeysOf<BaseType> extends never ? false : true;
Creates a type that represents
true
orfalse
depending on whether the given type has any writable fields.This is useful when you want to create an API whose behavior depends on the presence or absence of writable fields.
Example 1
import type {HasWritableKeys, WritableKeysOf} from 'type-fest';type UpdateService<Entity extends object> = {removeField: HasWritableKeys<Entity> extends true? (field: WritableKeysOf<Entity>) => Promise<void>: never}Utilities
type IfAny
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = IsAny<T> extends true ? TypeIfAny : TypeIfNotAny;
An if-else-like type that resolves depending on whether the given type is
any
.Example 1
import type {IfAny} from 'type-fest';type ShouldBeTrue = IfAny<any>;//=> truetype ShouldBeBar = IfAny<'not any', 'foo', 'bar'>;//=> 'bar'Type Guard Utilities
See Also
type IfEmptyObject
type IfEmptyObject< T, TypeIfEmptyObject = true, TypeIfNotEmptyObject = false> = IsEmptyObject<T> extends true ? TypeIfEmptyObject : TypeIfNotEmptyObject;
An if-else-like type that resolves depending on whether the given type is
{}
.Example 1
import type {IfEmptyObject} from 'type-fest';type ShouldBeTrue = IfEmptyObject<{}>;//=> truetype ShouldBeBar = IfEmptyObject<{key: any}, 'foo', 'bar'>;//=> 'bar'Type Guard Utilities
See Also
type IfNever
type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = IsNever<T> extends true ? TypeIfNever : TypeIfNotNever;
An if-else-like type that resolves depending on whether the given type is
never
.Example 1
import type {IfNever} from 'type-fest';type ShouldBeTrue = IfNever<never>;//=> truetype ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;//=> 'bar'Type Guard Utilities
See Also
type IfNull
type IfNull<T, TypeIfNull = true, TypeIfNotNull = false> = IsNull<T> extends true ? TypeIfNull : TypeIfNotNull;
An if-else-like type that resolves depending on whether the given type is
null
.Example 1
import type {IfNull} from 'type-fest';type ShouldBeTrue = IfNull<null>;//=> truetype ShouldBeBar = IfNull<'not null', 'foo', 'bar'>;//=> 'bar'Type Guard Utilities
See Also
type IfUnknown
type IfUnknown< T, TypeIfUnknown = true, TypeIfNotUnknown = false> = IsUnknown<T> extends true ? TypeIfUnknown : TypeIfNotUnknown;
An if-else-like type that resolves depending on whether the given type is
unknown
.Example 1
import type {IfUnknown} from 'type-fest';type ShouldBeTrue = IfUnknown<unknown>;//=> truetype ShouldBeBar = IfUnknown<'not unknown', 'foo', 'bar'>;//=> 'bar'Type Guard Utilities
See Also
type Includes
type Includes<Value extends readonly any[], Item> = Value extends readonly [ Value[0], ...infer rest] ? IsEqual<Value[0], Item> extends true ? true : Includes<rest, Item> : false;
Returns a boolean for whether the given array includes the given item.
This can be useful if another type wants to make a decision based on whether the array includes that item.
Example 1
import type {Includes} from 'type-fest';type hasRed<array extends any[]> = Includes<array, 'red'>;Array
type Integer
type Integer<T> = T extends unknown // To distributive type ? IsInteger<T> extends true ? T : never : never;
A
number
that is an integer.Use-case: Validating and documenting parameters.
Example 1
type Integer = Integer<1>;//=> 1type IntegerWithDecimal = Integer<1.0>;//=> 1type NegativeInteger = Integer<-1>;//=> -1type Float = Integer<1.5>;//=> never// Supports non-decimal numberstype OctalInteger: Integer<0o10>;//=> 0o10type BinaryInteger: Integer<0b10>;//=> 0b10type HexadecimalInteger: Integer<0x10>;//=> 0x10Example 2
import type {Integer} from 'type-fest';declare function setYear<T extends number>(length: Integer<T>): void;See Also
NegativeInteger
NonNegativeInteger
Numeric
type IntRange
type IntRange< Start extends number, End extends number, Step extends number = 1> = PrivateIntRange<Start, End, Step>;
Generate a union of numbers.
The numbers are created from the given
Start
(inclusive) parameter to the givenEnd
(exclusive) parameter.You skip over numbers using the
Step
parameter (defaults to1
). For example,IntRange<0, 10, 2>
will create a union of0 | 2 | 4 | 6 | 8
.Note:
Start
orEnd
must be non-negative and smaller than1000
.Use-cases: 1. This can be used to define a set of valid input/output values. for example: ``` type Age = IntRange<0, 120>; type FontSize = IntRange<10, 20>; type EvenNumber = IntRange<0, 11, 2>; //=> 0 | 2 | 4 | 6 | 8 | 10 ``` 2. This can be used to define random numbers in a range. For example,
type RandomNumber = IntRange<0, 100>;
Example 1
import type {IntRange} from 'type-fest';// Create union type `0 | 1 | ... | 9`type ZeroToNine = IntRange<0, 10>;// Create union type `100 | 200 | 300 | ... | 900`type Hundreds = IntRange<100, 901, 100>;
type InvariantOf
type InvariantOf<Type> = Type & { [invariantBrand]: (_: Type) => Type };
Create an [invariant type](https://basarat.gitbook.io/typescript/type-system/type-compatibility#footnote-invariance), which is a type that does not accept supertypes and subtypes.
Use-case: - Prevent runtime errors that may occur due to assigning subtypes to supertypes. - Improve type signature of object methods like [
Object.keys()
orObject.entries()
](https://github.com/microsoft/TypeScript/pull/12253#issuecomment-263132208) by sealing the object type.Example 1
import type {InvariantOf} from 'type-fest';class Animal {constructor(public name: string){}}class Cat extends Animal {meow() {}}let animalArray: Animal[] = [animal];let catArray: Cat[] = [cat];animalArray = catArray; // Okay if covariantanimalArray.push(new Animal('another animal')); // Pushed an animal into catArraycatArray.forEach(c => c.meow()); // Allowed but, error at runtimelet invariantAnimalArray: InvariantOf<Animal>[] = [animal] as InvariantOf<Animal>[];let invariantCatArray: InvariantOf<Cat>[] = [cat] as InvariantOf<Cat>[];invariantAnimalArray = invariantCatArray; // Error: Type 'InvariantOf<Cat>[]' is not assignable to type 'InvariantOf<Animal>[]'.Example 2
import type {InvariantOf} from 'type-fest';// In covariance (default)interface FooBar {foo: number;bar: string}interface FooBarBaz extends FooBar {baz: boolean}declare const fooBar: FooBardeclare const fooBarBaz: FooBarBazfunction keyOfFooBar(fooBar: FooBar) {return Object.keys(fooBar) as (keyof FooBar)[]}keyOfFooBar(fooBar) //=> (keyof FooBar)[]keyOfFooBar(fooBarBaz) //=> (keyof FooBar)[] but, (keyof FooBarBaz)[] at runtime// In invarianceexport function invariantOf<Type>(value: Type): InvariantOf<Type> {return value as InvariantOf<Type>;}function keyOfInvariantFooBar(fooBar: InvariantOf<FooBar>) {return Object.keys(fooBar) as (keyof FooBar)[]}keyOfInvariantFooBar(invariantOf(fooBar)); // (keyof FooBar)[]keyOfInvariantFooBar(invariantOf(fooBarBaz)); // Error: Argument of type 'InvariantOf<FooBarBaz>' is not assignable to parameter of type 'InvariantOf<FooBar>'.Type
type IsAny
type IsAny<T> = 0 extends 1 & T ? true : false;
Returns a boolean for whether the given type is
any
.https://stackoverflow.com/a/49928360/1490091
Useful in type utilities, such as disallowing
any
s to be passed to a function.Example 1
import type {IsAny} from 'type-fest';const typedObject = {a: 1, b: 2} as const;const anyObject: any = {a: 1, b: 2};function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {return obj[key];}const typedA = get(typedObject, 'a');//=> 1const anyA = get(anyObject, 'a');//=> anyType Guard Utilities
type IsBooleanLiteral
type IsBooleanLiteral<T> = LiteralCheck<T, boolean>;
Returns a boolean for whether the given type is a
true
orfalse
[literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs
Example 1
import type {IsBooleanLiteral} from 'type-fest';const id = 123;type GetId<AsString extends boolean> =IsBooleanLiteral<AsString> extends true? AsString extends true? `${typeof id}`: typeof id: number | string;function getId<AsString extends boolean = false>(options?: {asString: AsString}) {return (options?.asString ? `${id}` : id) as GetId<AsString>;}const numberId = getId();//=> 123const stringId = getId({asString: true});//=> '123'declare const runtimeBoolean: boolean;const eitherId = getId({asString: runtimeBoolean});//=> number | stringType Guard Utilities
type IsEmptyObject
type IsEmptyObject<T> = T extends EmptyObject ? true : false;
Returns a
boolean
for whether the type is strictly equal to an empty plain object, the{}
value.Example 1
import type {IsEmptyObject} from 'type-fest';type Pass = IsEmptyObject<{}>; //=> truetype Fail = IsEmptyObject<[]>; //=> falsetype Fail = IsEmptyObject<null>; //=> falseSee Also
EmptyObject Object
type IsEqual
type IsEqual<A, B> = (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2 ? true : false;
Returns a boolean for whether the two given types are equal.
https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
Use-cases: - If you want to make a conditional branch based on the result of a comparison of two types.
Example 1
import type {IsEqual} from 'type-fest';// This type returns a boolean for whether the given array includes the given item.// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.type Includes<Value extends readonly any[], Item> =Value extends readonly [Value[0], ...infer rest]? IsEqual<Value[0], Item> extends true? true: Includes<rest, Item>: false;Type Guard Utilities
type IsFloat
type IsFloat<T> = T extends number ? `${T}` extends `${infer _Sign extends | '' | '-'}${number}.${infer Decimal extends number}` ? Decimal extends Zero ? false : true : false : false;
Returns a boolean for whether the given number is a float, like
1.5
or-1.5
.It returns
false
forInfinity
.Use-case: - If you want to make a conditional branch based on the result of whether a number is a float or not.
Example 1
type Float = IsFloat<1.5>;//=> truetype IntegerWithDecimal = IsInteger<1.0>;//=> falsetype NegativeFloat = IsInteger<-1.5>;//=> truetype Infinity_ = IsInteger<Infinity>;//=> false
type IsInteger
type IsInteger<T> = T extends bigint ? true : T extends number ? number extends T ? false : T extends PositiveInfinity | NegativeInfinity ? false : Not<IsFloat<T>> : false;
Returns a boolean for whether the given number is a integer, like
-5
,1.0
or100
.Like [
Number#IsInteger()
](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/IsInteger) but for types.Use-case: - If you want to make a conditional branch based on the result of whether a number is a intrger or not.
Example 1
type Integer = IsInteger<1>;//=> truetype IntegerWithDecimal = IsInteger<1.0>;//=> truetype NegativeInteger = IsInteger<-1>;//=> truetype Float = IsInteger<1.5>;//=> false// Supports non-decimal numberstype OctalInteger: IsInteger<0o10>;//=> truetype BinaryInteger: IsInteger<0b10>;//=> truetype HexadecimalInteger: IsInteger<0x10>;//=> true
type IsLiteral
type IsLiteral<T> = IsPrimitive<T> extends true ? IsNotFalse<IsLiteralUnion<T>> : false;
Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs
Example 1
import type {IsLiteral} from 'type-fest';// https://github.com/inocan-group/inferred-types/blob/master/src/types/string-literals/StripLeading.tsexport type StripLeading<A, B> =A extends string? B extends string? IsLiteral<A> extends true? string extends B ? never : A extends `${B & string}${infer After}` ? After : A: string: A: A;function stripLeading<Input extends string, Strip extends string>(input: Input, strip: Strip) {return input.replace(`^${strip}`, '') as StripLeading<Input, Strip>;}stripLeading('abc123', 'abc');//=> '123'const str = 'abc123' as string;stripLeading(str, 'abc');//=> stringType Guard Utilities
type IsNegative
type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
Returns a boolean for whether the given number is a negative number.
Example 1
import type {IsNegative} from 'type-fest';type ShouldBeFalse = IsNegative<1>;type ShouldBeTrue = IsNegative<-1>;Numeric
See Also
Negative
type IsNever
type IsNever<T> = [T] extends [never] ? true : false;
Returns a boolean for whether the given type is
never
.https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919 https://stackoverflow.com/a/53984913/10292952 https://www.zhenghao.io/posts/ts-never
Useful in type utilities, such as checking if something does not occur.
Example 1
import type {IsNever, And} from 'type-fest';// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.tstype AreStringsEqual<A extends string, B extends string> =And<IsNever<Exclude<A, B>> extends true ? true : false,IsNever<Exclude<B, A>> extends true ? true : false>;type EndIfEqual<I extends string, O extends string> =AreStringsEqual<I, O> extends true? never: void;function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {if (input === output) {process.exit(0);}}endIfEqual('abc', 'abc');//=> neverendIfEqual('abc', '123');//=> voidType Guard Utilities
type IsNull
type IsNull<T> = [T] extends [null] ? true : false;
Returns a boolean for whether the given type is
null
.Example 1
import type {IsNull} from 'type-fest';type NonNullFallback<T, Fallback> = IsNull<T> extends true ? Fallback : T;type Example1 = NonNullFallback<null, string>;//=> stringtype Example2 = NonNullFallback<number, string>;//=? numberType Guard Utilities
type IsNumericLiteral
type IsNumericLiteral<T> = LiteralChecks<T, Numeric>;
Returns a boolean for whether the given type is a
number
orbigint
[literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs
Example 1
import type {IsNumericLiteral} from 'type-fest';// https://github.com/inocan-group/inferred-types/blob/master/src/types/boolean-logic/EndsWith.tstype EndsWith<TValue, TEndsWith extends string> =TValue extends string? IsStringLiteral<TEndsWith> extends true? IsStringLiteral<TValue> extends true? TValue extends `${string}${TEndsWith}`? true: false: boolean: boolean: TValue extends number? IsNumericLiteral<TValue> extends true? EndsWith<`${TValue}`, TEndsWith>: false: false;function endsWith<Input extends string | number, End extends string>(input: Input, end: End) {return `${input}`.endsWith(end) as EndsWith<Input, End>;}endsWith('abc', 'c');//=> trueendsWith(123456, '456');//=> trueconst end = '123' as string;endsWith('abc123', end);//=> booleanType Guard Utilities
type IsStringLiteral
type IsStringLiteral<T> = LiteralCheck<T, string>;
Returns a boolean for whether the given type is a
string
[literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).Useful for: - providing strongly-typed string manipulation functions - constraining strings to be a string literal - type utilities, such as when constructing parsers and ASTs
Example 1
import type {IsStringLiteral} from 'type-fest';type CapitalizedString<T extends string> = IsStringLiteral<T> extends true ? Capitalize<T> : string;// https://github.com/yankeeinlondon/native-dash/blob/master/src/capitalize.tsfunction capitalize<T extends Readonly<string>>(input: T): CapitalizedString<T> {return (input.slice(0, 1).toUpperCase() + input.slice(1)) as CapitalizedString<T>;}const output = capitalize('hello, world!');//=> 'Hello, world!'Type Guard Utilities
type IsSymbolLiteral
type IsSymbolLiteral<T> = LiteralCheck<T, symbol>;
Returns a boolean for whether the given type is a
symbol
[literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).Useful for: - providing strongly-typed functions when given literal arguments - type utilities, such as when constructing parsers and ASTs
Example 1
import type {IsSymbolLiteral} from 'type-fest';type Get<Obj extends Record<symbol, number>, Key extends keyof Obj> =IsSymbolLiteral<Key> extends true? Obj[Key]: number;function get<Obj extends Record<symbol, number>, Key extends keyof Obj>(o: Obj, key: Key) {return o[key] as Get<Obj, Key>;}const symbolLiteral = Symbol('literal');const symbolValue: symbol = Symbol('value');get({[symbolLiteral]: 1} as const, symbolLiteral);//=> 1get({[symbolValue]: 1} as const, symbolValue);//=> numberType Guard Utilities
type IsUnknown
type IsUnknown<T> = unknown extends T // `T` can be `unknown` or `any` ? IsNull<T> extends false // `any` can be `null`, but `unknown` can't be ? true : false : false;
Returns a boolean for whether the given type is
unknown
.https://github.com/dsherret/conditional-type-checks/pull/16
Useful in type utilities, such as when dealing with unknown data from API calls.
Example 1
import type {IsUnknown} from 'type-fest';// https://github.com/pajecawav/tiny-global-store/blob/master/src/index.tstype Action<TState, TPayload = void> =IsUnknown<TPayload> extends true? (state: TState) => TState,: (state: TState, payload: TPayload) => TState;class Store<TState> {constructor(private state: TState) {}execute<TPayload = void>(action: Action<TState, TPayload>, payload?: TPayload): TState {this.state = action(this.state, payload);return this.state;}// ... other methods}const store = new Store({value: 1});declare const someExternalData: unknown;store.execute(state => ({value: state.value + 1}));//=> `TPayload` is `void`store.execute((state, payload) => ({value: state.value + payload}), 5);//=> `TPayload` is `5`store.execute((state, payload) => ({value: state.value + payload}), someExternalData);//=> Errors: `action` is `(state: TState) => TState`Utilities
type IterableElement
type IterableElement<TargetIterable> = TargetIterable extends Iterable< infer ElementType> ? ElementType : TargetIterable extends AsyncIterable<infer ElementType> ? ElementType : never;
Get the element type of an
Iterable
/AsyncIterable
. For example,Array
,Set
,Map
, generator, stream, etc.This can be useful, for example, if you want to get the type that is yielded in a generator function. Often the return type of those functions are not specified.
This type works with both
Iterable
s andAsyncIterable
s, so it can be use with synchronous and asynchronous generators.Here is an example of
IterableElement
in action with a generator function:Example 1
import type {IterableElement} from 'type-fest';function * iAmGenerator() {yield 1;yield 2;}type MeNumber = IterableElement<ReturnType<typeof iAmGenerator>>And here is an example with an async generator:
Example 2
import type {IterableElement} from 'type-fest';async function * iAmGeneratorAsync() {yield 'hi';yield true;}type MeStringOrBoolean = IterableElement<ReturnType<typeof iAmGeneratorAsync>>Many types in JavaScript/TypeScript are iterables. This type works on all types that implement those interfaces.
An example with an array of strings:
Example 3
import type {IterableElement} from 'type-fest';type MeString = IterableElement<string[]>Example 4
import type {IterableElement} from 'type-fest';const fruits = new Set(['🍎', '🍌', '🍉'] as const);type Fruit = IterableElement<typeof fruits>;//=> '🍎' | '🍌' | '🍉'Iterable
type Join
type Join< Items extends readonly JoinableItem[], Delimiter extends string> = Items extends readonly [] ? '' : Items extends readonly [JoinableItem?] ? `${NullishCoalesce<Items[0], ''>}` : Items extends readonly [ infer First extends JoinableItem, ...infer Tail extends readonly JoinableItem[] ] ? `${NullishCoalesce<First, ''>}${Delimiter}${Join<Tail, Delimiter>}` : Items extends readonly [ ...infer Head extends readonly JoinableItem[], infer Last extends JoinableItem ] ? `${Join<Head, Delimiter>}${Delimiter}${NullishCoalesce<Last, ''>}` : string;
Join an array of strings and/or numbers using the given string as a delimiter.
Use-case: Defining key paths in a nested object. For example, for dot-notation fields in MongoDB queries.
Example 1
import type {Join} from 'type-fest';// Mixed (strings & numbers) items; result is: 'foo.0.baz'const path: Join<['foo', 0, 'baz'], '.'> = ['foo', 0, 'baz'].join('.');// Only string items; result is: 'foo.bar.baz'const path: Join<['foo', 'bar', 'baz'], '.'> = ['foo', 'bar', 'baz'].join('.');// Only number items; result is: '1.2.3'const path: Join<[1, 2, 3], '.'> = [1, 2, 3].join('.');// Only bigint items; result is '1.2.3'const path: Join<[1n, 2n, 3n], '.'> = [1n, 2n, 3n].join('.');// Only boolean items; result is: 'true.false.true'const path: Join<[true, false, true], '.'> = [true, false, true].join('.');// Contains nullish items; result is: 'foo..baz..xyz'const path: Join<['foo', undefined, 'baz', null, 'xyz'], '.'> = ['foo', undefined, 'baz', null, 'xyz'].join('.');// Partial tuple shapes (rest param last); result is: `prefix.${string}`const path: Join<['prefix', ...string[]], '.'> = ['prefix'].join('.');// Partial tuple shapes (rest param first); result is: `${string}.suffix`const path: Join<[...string[], 'suffix'], '.'> = ['suffix'].join('.');// Tuples items with nullish unions; result is '.' | 'hello.' | '.world' | 'hello.world'const path: Join<['hello' | undefined, 'world' | null], '.'> = ['hello', 'world'].join('.');Array Template literal
type JsonArray
type JsonArray = JsonValue[] | readonly JsonValue[];
Matches a JSON array.
JSON
type Jsonifiable
type Jsonifiable = JsonPrimitive | JsonifiableObject | JsonifiableArray;
Matches a value that can be losslessly converted to JSON.
Can be used to type values that you expect to pass to
JSON.stringify
.undefined
is allowed in object fields (for example,{a?: number}
) as a special case even thoughJSON.stringify({a: undefined})
is{}
because it makes this class more widely useful and checking for undefined-but-present values is likely an anti-pattern.Example 1
import type {Jsonifiable} from 'type-fest';// @ts-expect-errorconst error: Jsonifiable = {map: new Map([['a', 1]]),};JSON.stringify(error);//=> {"map": {}}const good: Jsonifiable = {number: 3,date: new Date(),missing: undefined,}JSON.stringify(good);//=> {"number": 3, "date": "2022-10-17T22:22:35.920Z"}JSON
type Jsonify
type Jsonify<T> = IsAny<T> extends true ? any : T extends PositiveInfinity | NegativeInfinity ? null : T extends JsonPrimitive ? T : // Any object with toJSON is special case T extends { toJSON(): infer J } ? (() => J) extends () => JsonValue // Is J assignable to JsonValue? ? J // Then T is Jsonable and its Jsonable value is J : Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue : // Instanced primitives are objects T extends Number ? number : T extends String ? string : T extends Boolean ? boolean : T extends Map<any, any> | Set<any> ? EmptyObject : T extends TypedArray ? Record<string, number> : T extends NotJsonable ? never // Non-JSONable type union was found not empty : T extends UnknownArray ? JsonifyList<T> : T extends object ? JsonifyObject<UndefinedToOptional<T>> // JsonifyObject recursive call for its children : never;
Transform a type to one that is assignable to the
JsonValue
type.This includes: 1. Transforming JSON
interface
to atype
that is assignable toJsonValue
. 2. Transforming non-JSON value that is *jsonable* to a type that is assignable toJsonValue
, where *jsonable* means the non-JSON value implements the.toJSON()
method that returns a value that is assignable toJsonValue
.Remarks
An interface cannot be structurally compared to
JsonValue
because an interface can be re-opened to add properties that may not be satisfyJsonValue
.Example 1
import type {Jsonify, JsonValue} from 'type-fest';interface Geometry {type: 'Point' | 'Polygon';coordinates: [number, number];}const point: Geometry = {type: 'Point',coordinates: [1, 1]};const problemFn = (data: JsonValue) => {// Does something with data};problemFn(point); // Error: type Geometry is not assignable to parameter of type JsonValue because it is an interfaceconst fixedFn = <T>(data: Jsonify<T>) => {// Does something with data};fixedFn(point); // Good: point is assignable. Jsonify<T> transforms Geometry into value assignable to JsonValuefixedFn(new Date()); // Error: As expected, Date is not assignable. Jsonify<T> cannot transforms Date into value assignable to JsonValueNon-JSON values such as
Date
implement.toJSON()
, so they can be transformed to a value assignable toJsonValue
:Example 2
import type {Jsonify} from 'type-fest';const time = {timeValue: new Date()};// `Jsonify<typeof time>` is equivalent to `{timeValue: string}`const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>;https://github.com/Microsoft/TypeScript/issues/1897#issuecomment-710744173
JSON
type JsonObject
type JsonObject = { [Key in string]: JsonValue } & { [Key in string]?: JsonValue | undefined;};
Matches a JSON object.
This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it:
jsonObject as unknown as CustomResponse
. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types:interface CustomResponse extends JsonObject { … }
.JSON
type JsonPrimitive
type JsonPrimitive = string | number | boolean | null;
Matches any valid JSON primitive value.
JSON
type JsonValue
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
Matches any valid JSON value.
See Also
Jsonify
if you need to transform a type to one that is assignable toJsonValue
.JSON
type KebabCase
type KebabCase<Value> = DelimiterCase<Value, '-'>;
Convert a string literal to kebab-case.
This can be useful when, for example, converting a camel-cased object property to a kebab-cased CSS class name or a command-line flag.
Example 1
import type {KebabCase} from 'type-fest';// Simpleconst someVariable: KebabCase<'fooBar'> = 'foo-bar';// Advancedtype KebabCasedProperties<T> = {[K in keyof T as KebabCase<K>]: T[K]};interface CliOptions {dryRun: boolean;includeFile: string;foo: number;}const rawCliOptions: KebabCasedProperties<CliOptions> = {'dry-run': true,'include-file': 'bar.js',foo: 123};Change case Template literal
type KebabCasedProperties
type KebabCasedProperties<Value> = DelimiterCasedProperties<Value, '-'>;
Convert object properties to kebab case but not recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {KebabCasedProperties} from 'type-fest';interface User {userId: number;userName: string;}const result: KebabCasedProperties<User> = {'user-id': 1,'user-name': 'Tom',};Change case Template literal Object
See Also
KebabCase
KebabCasedPropertiesDeep
type KebabCasedPropertiesDeep
type KebabCasedPropertiesDeep<Value> = DelimiterCasedPropertiesDeep<Value, '-'>;
Convert object properties to kebab case recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type [KebabCasedPropertiesDeep] from 'type-fest';interface User {userId: number;userName: string;}interface UserWithFriends {userInfo: User;userFriends: User[];}const result: KebabCasedPropertiesDeep<UserWithFriends> = {'user-info': {'user-id': 1,'user-name': 'Tom',},'user-friends': [{'user-id': 2,'user-name': 'Jerry',},{'user-id': 3,'user-name': 'Spike',},],};Change case Template literal Object
See Also
KebabCase
KebabCasedProperties
type KeysOfUnion
type KeysOfUnion<ObjectType> = ObjectType extends unknown ? keyof ObjectType : never;
Create a union of all keys from a given type, even those exclusive to specific union members.
Unlike the native
keyof
keyword, which returns keys present in **all** union members, this type returns keys from **any** member.https://stackoverflow.com/a/49402091
Example 1
import type {KeysOfUnion} from 'type-fest';type A = {common: string;a: number;};type B = {common: string;b: string;};type C = {common: string;c: boolean;};type Union = A | B | C;type CommonKeys = keyof Union;//=> 'common'type AllKeys = KeysOfUnion<Union>;//=> 'common' | 'a' | 'b' | 'c'Object
type LastArrayElement
type LastArrayElement< Elements extends readonly unknown[], ElementBeforeTailingSpreadElement = never> = // If the last element of an array is a spread element, the `LastArrayElement` result should be `'the type of the element before the spread element' | 'the type of the spread element'`. Elements extends readonly [] ? ElementBeforeTailingSpreadElement : Elements extends readonly [...infer U, infer V] ? V : Elements extends readonly [infer U, ...infer V] ? // If we return `V[number] | U` directly, it would be wrong for `[[string, boolean, object, ...number[]]`. // So we need to recurse type `V` and carry over the type of the element before the spread element. LastArrayElement<V, U> : Elements extends ReadonlyArray<infer U> ? U | ElementBeforeTailingSpreadElement : never;
Extracts the type of the last element of an array.
Use-case: Defining the return type of functions that extract the last element of an array, for example [
lodash.last
](https://lodash.com/docs/4.17.15#last).Example 1
import type {LastArrayElement} from 'type-fest';declare function lastOf<V extends readonly any[]>(array: V): LastArrayElement<V>;const array = ['foo', 2];typeof lastOf(array);//=> numberconst array = ['foo', 2] as const;typeof lastOf(array);//=> 2Array Template literal
type LessThan
type LessThan<A extends number, B extends number> = number extends A | B ? never : GreaterThanOrEqual<A, B> extends true ? false : true;
Returns a boolean for whether a given number is less than another number.
Example 1
import type {LessThan} from 'type-fest';LessThan<1, -5>;//=> falseLessThan<1, 1>;//=> falseLessThan<1, 5>;//=> true
type LessThanOrEqual
type LessThanOrEqual<A extends number, B extends number> = number extends A | B ? never : GreaterThan<A, B> extends true ? false : true;
Returns a boolean for whether a given number is less than or equal to another number.
Example 1
import type {LessThanOrEqual} from 'type-fest';LessThanOrEqual<1, -5>;//=> falseLessThanOrEqual<1, 1>;//=> trueLessThanOrEqual<1, 5>;//=> true
type LiteralToPrimitive
type LiteralToPrimitive<T> = T extends number ? number : T extends bigint ? bigint : T extends string ? string : T extends boolean ? boolean : T extends symbol ? symbol : T extends null ? null : T extends undefined ? undefined : never;
Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the primitive type it belongs to, or
never
if it's not a primitive.Use-case: Working with generic types that may be literal types.
Example 1
import type {LiteralToPrimitive} from 'type-fest';// No overloads needed to get the correct return typefunction plus<T extends number | bigint | string>(x: T, y: T): LiteralToPrimitive<T> {return x + (y as any);}plus('a', 'b'); // stringplus(1, 2); // numberplus(1n, 2n); // bigintType
type LiteralToPrimitiveDeep
type LiteralToPrimitiveDeep<T> = T extends object ? T extends Array<infer U> ? Array<LiteralToPrimitiveDeep<U>> : { [K in keyof OmitIndexSignature<T>]: LiteralToPrimitiveDeep<T[K]>; } : LiteralToPrimitive<T>;
Like
LiteralToPrimitive
except it converts literal types inside an object or array deeply.For example, given a constant object, it returns a new object type with the same keys but with all the values converted to primitives.
Example 1
import type {LiteralToPrimitiveDeep, TsConfigJson} from 'type-fest';import tsconfig from 'path/to/tsconfig.json';function doSomethingWithTSConfig(config: LiteralToPrimitiveDeep<TsConfigJson>) { ... }// No casting is needed to pass the type checkdoSomethingWithTSConfig(tsconfig);// If LiteralToPrimitiveDeep is not used, you need to cast the imported data like this:doSomethingWithTSConfig(tsconfig as TsConfigJson);Type Object
See Also
LiteralToPrimitive
Use-case: Deal with data that is imported from a JSON file.
type LiteralUnion
type LiteralUnion<LiteralType, BaseType extends Primitive> = | LiteralType | (BaseType & Record<never, never>);
Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore.
Example 1
import type {LiteralUnion} from 'type-fest';// Beforetype Pet = 'dog' | 'cat' | string;const pet: Pet = '';// Start typing in your TypeScript-enabled IDE.// You **will not** get auto-completion for `dog` and `cat` literals.// Aftertype Pet2 = LiteralUnion<'dog' | 'cat', string>;const pet: Pet2 = '';// You **will** get auto-completion for `dog` and `cat` literals.Type
type Merge
type Merge<Destination, Source> = Simplify< SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
Merge two types into a new type. Keys of the second type overrides keys of the first type.
Example 1
import type {Merge} from 'type-fest';interface Foo {[x: string]: unknown;[x: number]: unknown;foo: string;bar: symbol;}type Bar = {[x: number]: number;[x: symbol]: unknown;bar: Date;baz: boolean;};export type FooBar = Merge<Foo, Bar>;// => {// [x: string]: unknown;// [x: number]: number;// [x: symbol]: unknown;// foo: string;// bar: Date;// baz: boolean;// }Object
type MergeDeep
type MergeDeep< Destination, Source, Options extends MergeDeepOptions = {}> = MergeDeepWithDefaultOptions< SimplifyDeepExcludeArray<Destination>, SimplifyDeepExcludeArray<Source>, Options>;
Merge two objects or two arrays/tuples recursively into a new type.
- Properties that only exist in one object are copied into the new object. - Properties that exist in both objects are merged if possible or replaced by the one of the source if not. - Top-level arrays and tuples are always spread. - By default, inner arrays and tuples are replaced. See option to change this behaviour. - By default, individual array/tuple elements are not affected. See option to change this behaviour.
Example 1
import type {MergeDeep} from 'type-fest';type Foo = {life: number;items: string[];a: {b: string; c: boolean; d: number[]};};interface Bar {name: string;items: number[];a: {b: number; d: boolean[]};}type FooBar = MergeDeep<Foo, Bar>;// {// life: number;// name: string;// items: number[];// a: {b: number; c: boolean; d: boolean[]};// }type FooBar = MergeDeep<Foo, Bar, {arrayMergeMode: 'spread'}>;// {// life: number;// name: string;// items: (string | number)[];// a: {b: number; c: boolean; d: (number | boolean)[]};// }Example 2
import type {MergeDeep} from 'type-fest';// Merge two arraystype ArrayMerge = MergeDeep<string[], number[]>; // => (string | number)[]// Merge two tuplestype TupleMerge = MergeDeep<[1, 2, 3], ['a', 'b']>; // => (1 | 2 | 3 | 'a' | 'b')[]// Merge an array into a tupletype TupleArrayMerge = MergeDeep<[1, 2, 3], string[]>; // => (string | 1 | 2 | 3)[]// Merge a tuple into an arraytype ArrayTupleMerge = MergeDeep<number[], ['a', 'b']>; // => (number | 'b' | 'a')[]Example 3
import type {MergeDeep, MergeDeepOptions} from 'type-fest';type Foo = {foo: 'foo'; fooBar: string[]};type Bar = {bar: 'bar'; fooBar: number[]};type FooBar = MergeDeep<Foo, Bar>;// { foo: "foo"; bar: "bar"; fooBar: number[]}type FooBarSpread = MergeDeep<Foo, Bar, {arrayMergeMode: 'spread'}>;// { foo: "foo"; bar: "bar"; fooBar: (string | number)[]}type FooBarArray = MergeDeep<Foo[], Bar[]>;// (Foo | Bar)[]type FooBarArrayDeep = MergeDeep<Foo[], Bar[], {recurseIntoArrays: true}>;// FooBar[]type FooBarArraySpreadDeep = MergeDeep<Foo[], Bar[], {recurseIntoArrays: true; arrayMergeMode: 'spread'}>;// FooBarSpread[]type FooBarTupleDeep = MergeDeep<[Foo, true, 42], [Bar, 'life'], {recurseIntoArrays: true}>;// [FooBar, 'life', 42]type FooBarTupleWithArrayDeep = MergeDeep<[Foo[], true], [Bar[], 'life', 42], {recurseIntoArrays: true}>;// [FooBar[], 'life', 42]Example 4
import type {MergeDeep, MergeDeepOptions} from 'type-fest';function mergeDeep<Destination, Source, Options extends MergeDeepOptions = {}>(destination: Destination,source: Source,options?: Options,): MergeDeep<Destination, Source, Options> {// Make your implementation ...}This type is marked as experimental because it depends on ConditionalSimplifyDeep which itself is experimental.
See Also
Array Object Utilities
Modifiers
@experimental
type MergeDeepOptions
type MergeDeepOptions = { /** Merge mode for array and tuple.
When we walk through the properties of the objects and the same key is found and both are array or tuple, a merge mode must be chosen: - `replace`: Replaces the destination value by the source value. This is the default mode. - `spread`: Spreads the destination and the source values.
See {@link MergeDeep} for usages and examples.
Note: Top-level arrays and tuples are always spread.
@default 'replace' */ arrayMergeMode?: ArrayMergeMode;
/** Whether to affect the individual elements of arrays and tuples.
If this option is set to `true` the following rules are applied: - If the source does not contain the key, the value of the destination is returned. - If the source contains the key and the destination does not contain the key, the value of the source is returned. - If both contain the key, try to merge according to the chosen {@link MergeDeepOptions.arrayMergeMode arrayMergeMode} or return the source if unable to merge.
@default false */ recurseIntoArrays?: boolean;};
MergeDeep options.
See Also
type MergeExclusive
type MergeExclusive<FirstType, SecondType> = FirstType | SecondType extends object ? | (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) : FirstType | SecondType;
Create a type that has mutually exclusive keys.
This type was inspired by [this comment](https://github.com/Microsoft/TypeScript/issues/14094#issuecomment-373782604).
This type works with a helper type, called
Without
.Without<FirstType, SecondType>
produces a type that has only keys fromFirstType
which are not present onSecondType
and sets the value type for these keys tonever
. This helper type is then used inMergeExclusive
to remove keys from eitherFirstType
orSecondType
.Example 1
import type {MergeExclusive} from 'type-fest';interface ExclusiveVariation1 {exclusive1: boolean;}interface ExclusiveVariation2 {exclusive2: string;}type ExclusiveOptions = MergeExclusive<ExclusiveVariation1, ExclusiveVariation2>;let exclusiveOptions: ExclusiveOptions;exclusiveOptions = {exclusive1: true};//=> WorksexclusiveOptions = {exclusive2: 'hi'};//=> WorksexclusiveOptions = {exclusive1: true, exclusive2: 'hi'};//=> ErrorObject
type MultidimensionalArray
type MultidimensionalArray< Element, Dimensions extends number> = number extends Dimensions ? Recursive<Element> : IsEqual<Dimensions, 0> extends true ? Element : Array<MultidimensionalArray<Element, Subtract<Dimensions, 1>>>;
Creates a type that represents a multidimensional array of the given type and dimension.
Use-cases: - Return a n-dimensional array from functions. - Declare a n-dimensional array by defining its dimensions rather than declaring
[]
repetitively. - Infer the dimensions of a n-dimensional array automatically from function arguments. - Avoid the need to know in advance the dimensions of a n-dimensional array allowing them to be dynamic.Example 1
import type {MultidimensionalArray} from 'type-fest';function emptyMatrix<T extends number>(dimensions: T): MultidimensionalArray<unknown, T> {const matrix: unknown[] = [];let subMatrix = matrix;for (let dimension = 1; dimension < dimensions; ++dimension) {console.log(`Initializing dimension #${dimension}`);subMatrix[0] = [];subMatrix = subMatrix[0] as unknown[];}return matrix as MultidimensionalArray<unknown, T>;}const matrix = emptyMatrix(3);matrix[0][0][0] = 42;Array
type MultidimensionalReadonlyArray
type MultidimensionalReadonlyArray< Element, Dimensions extends number> = number extends Dimensions ? Recursive<Element> : IsEqual<Dimensions, 0> extends true ? Element : ReadonlyArray<MultidimensionalReadonlyArray<Element, Subtract<Dimensions, 1>>>;
Creates a type that represents a multidimensional readonly array that of the given type and dimension.
Use-cases: - Return a n-dimensional array from functions. - Declare a n-dimensional array by defining its dimensions rather than declaring
[]
repetitively. - Infer the dimensions of a n-dimensional array automatically from function arguments. - Avoid the need to know in advance the dimensions of a n-dimensional array allowing them to be dynamic.Example 1
import type {MultidimensionalReadonlyArray} from 'type-fest';function emptyMatrix<T extends number>(dimensions: T): MultidimensionalReadonlyArray<unknown, T> {const matrix: unknown[] = [];let subMatrix = matrix;for (let dimension = 1; dimension < dimensions; ++dimension) {console.log(`Initializing dimension #${dimension}`);subMatrix[0] = [];if (dimension < dimensions - 1) {subMatrix = subMatrix[0] as unknown[];} else {subMatrix[0] = 42;}}return matrix as MultidimensionalReadonlyArray<unknown, T>;}const matrix = emptyMatrix(3);const answer = matrix[0][0][0]; // 42Array
type Negative
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never;
A negative
number
/bigint
(-∞ < x < 0
)Use-case: Validating and documenting parameters.
See Also
NegativeInteger
NonNegative
Numeric
type NegativeFloat
type NegativeFloat<T extends number> = Negative<Float<T>>;
A negative (
-∞ < x < 0
)number
that is not an integer. Equivalent toNegative<Float<T>>
.Use-case: Validating and documenting parameters.
See Also
Negative
Float
Numeric
type NegativeInfinity
type NegativeInfinity = -1e999;
Matches the hidden
-Infinity
type.Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
See Also
PositiveInfinity
Numeric
type NegativeInteger
type NegativeInteger<T extends number> = Negative<Integer<T>>;
A negative (
-∞ < x < 0
)number
that is an integer. Equivalent toNegative<Integer<T>>
.You can't pass a
bigint
as they are already guaranteed to be integers, instead useNegative<T>
.Use-case: Validating and documenting parameters.
See Also
Negative
Integer
Numeric
type NonEmptyObject
type NonEmptyObject<T extends object> = HasRequiredKeys<T> extends true ? T : RequireAtLeastOne<T, keyof T>;
Represents an object with at least 1 non-optional key.
This is useful when you need an object where all keys are optional, but there must be at least 1 key.
Example 1
import type {NonEmptyObject} from 'type-fest';type User = {name: string;surname: string;id: number;};type UpdateRequest<Entity extends object> = NonEmptyObject<Partial<Entity>>;const update1: UpdateRequest<User> = {name: 'Alice',surname: 'Acme',};// At least 1 key is required, therefore this will report a 2322 error:// Type '{}' is not assignable to type 'UpdateRequest<User>'const update2: UpdateRequest<User> = {};See Also
Use
IsEmptyObject
to check whether an object is empty.Object
type NonEmptyTuple
type NonEmptyTuple<T = unknown> = readonly [T, ...T[]];
Matches any non-empty tuple.
Example 1
import type {NonEmptyTuple} from 'type-fest';const sum = (...numbers: NonEmptyTuple<number>) => numbers.reduce((total, value) => total + value, 0);sum(1, 2, 3);//=> 6sum();//=> Error: Expected at least 1 arguments, but got 0.See Also
RequireAtLeastOne for objects
Array
type NonNegative
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : never;
A non-negative
number
/bigint
(0 <= x < ∞
).Use-case: Validating and documenting parameters.
Example 1
import type {NonNegative} from 'type-fest';declare function setLength<T extends number>(length: NonNegative<T>): void;Numeric
See Also
NonNegativeInteger
Negative
type NonNegativeInteger
type NonNegativeInteger<T extends number> = NonNegative<Integer<T>>;
A non-negative (
0 <= x < ∞
)number
that is an integer. Equivalent toNonNegative<Integer<T>>
.You can't pass a
bigint
as they are already guaranteed to be integers, instead useNonNegative<T>
.Use-case: Validating and documenting parameters.
Example 1
import type {NonNegativeInteger} from 'type-fest';declare function setLength<T extends number>(length: NonNegativeInteger<T>): void;Numeric
See Also
NonNegative
Integer
type ObservableLike
type ObservableLike<ValueType = unknown> = { subscribe(observer?: Partial<Observer<ValueType>>): Unsubscribable; [Symbol.observable](): ObservableLike<ValueType>;};
Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable).
Remarks
The TC39 Observable proposal defines 2 forms of
subscribe()
: 1. Three callback arguments:subscribe(observer: OnNext<ValueType>, onError?: OnError, onComplete?: OnComplete): Unsubscribable;
2. A singleobserver
argument: (as defined below)But
Observable
implementations have evolved to preferring case 2 and some implementations choose not to implement case 1. Therefore, anObservableLike
cannot be trusted to implement the first case. (xstream and hand built observerables often do not implement case 1)See Also
https://github.com/tc39/proposal-observable#observable
https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L246-L259
https://benlesh.com/posts/learning-observable-by-building-observable/
Observable
type Observer
type Observer<ValueType> = { next: OnNext<ValueType>; error: OnError; complete: OnComplete;};
Observable
type OmitDeep
type OmitDeep<T, PathUnion extends LiteralUnion<Paths<T>, string>> = SimplifyDeep< SharedUnionFieldsDeep< { [P in PathUnion]: OmitDeepWithOnePath<T, P> }[PathUnion] >, UnknownArray>;
Omit properties from a deeply-nested object.
It supports recursing into arrays.
It supports removing specific items from an array, replacing each removed item with unknown at the specified index.
Use-case: Remove unneeded parts of complex objects.
Use [
Omit
](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) if you only need one level deep.Example 1
import type {OmitDeep} from 'type-fest';type Info = {userInfo: {name: string;uselessInfo: {foo: string;};};};type UsefulInfo = OmitDeep<Info, 'userInfo.uselessInfo'>;// type UsefulInfo = {// userInfo: {// name: string;// };// };// Supports removing multiple pathstype Info1 = {userInfo: {name: string;uselessField: string;uselessInfo: {foo: string;};};};type UsefulInfo1 = OmitDeep<Info1, 'userInfo.uselessInfo' | 'userInfo.uselessField'>;// type UsefulInfo1 = {// userInfo: {// name: string;// };// };// Supports arraytype A = OmitDeep<[1, 'foo', 2], 1>;// type A = [1, unknown, 2];// Supports recursing into arraytype Info1 = {address: [{street: string},{street2: string,foo: string};];}type AddressInfo = OmitDeep<Info1, 'address.1.foo'>;// type AddressInfo = {// address: [// {// street: string;// },// {// street2: string;// };// ];// };Object Array
type OmitIndexSignature
type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType];};
Omit any index signatures from the given object type, leaving only explicitly defined properties.
This is the counterpart of
PickIndexSignature
.Use-cases: - Remove overly permissive signatures from third-party types.
This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
It relies on the fact that an empty object (
{}
) is assignable to an object with just an index signature, likeRecord<string, unknown>
, but not to an object with explicitly defined keys, likeRecord<'foo' | 'bar', unknown>
.(The actual value type,
unknown
, is irrelevant and could be any type. Only the key type matters.)const indexed: Record<string, unknown> = {}; // Allowedconst keyed: Record<'foo', unknown> = {}; // Error// => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, barInstead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another:
type Indexed = {} extends Record<string, unknown>? '✅ `{}` is assignable to `Record<string, unknown>`': '❌ `{}` is NOT assignable to `Record<string, unknown>`';// => '✅ `{}` is assignable to `Record<string, unknown>`'type Keyed = {} extends Record<'foo' | 'bar', unknown>? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`": "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each
KeyType
ofObjectType
...import type {OmitIndexSignature} from 'type-fest';type OmitIndexSignature<ObjectType> = {[KeyType in keyof ObjectType // Map each key of `ObjectType`...]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.};...whether an empty object (
{}
) would be assignable to an object with thatKeyType
(Record<KeyType, unknown>
)...import type {OmitIndexSignature} from 'type-fest';type OmitIndexSignature<ObjectType> = {[KeyType in keyof ObjectType// Is `{}` assignable to `Record<KeyType, unknown>`?as {} extends Record<KeyType, unknown>? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`: ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`]: ObjectType[KeyType];};If
{}
is assignable, it means thatKeyType
is an index signature and we want to remove it. If it is not assignable,KeyType
is a "real" key and we want to keep it.import type {OmitIndexSignature} from 'type-fest';type OmitIndexSignature<ObjectType> = {[KeyType in keyof ObjectTypeas {} extends Record<KeyType, unknown>? never // => Remove this `KeyType`.: KeyType // => Keep this `KeyType` as it is.]: ObjectType[KeyType];};Example 1
import type {OmitIndexSignature} from 'type-fest';interface Example {// These index signatures will be removed.[x: string]: any[x: number]: any[x: symbol]: any[x: `head-${string}`]: string[x: `${string}-tail`]: string[x: `head-${string}-tail`]: string[x: `${bigint}`]: string[x: `embedded-${number}`]: string// These explicitly defined keys will remain.foo: 'bar';qux?: 'baz';}type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;// => { foo: 'bar'; qux?: 'baz' | undefined; }See Also
PickIndexSignature Object
type OnComplete
type OnComplete = () => void;
Observable
type OnError
type OnError = (error: unknown) => void;
Observable
type OnNext
type OnNext<ValueType> = (value: ValueType) => void;
Observable
type Opaque
type Opaque<Type, Token = unknown> = Type & TagContainer<Token>;
Note: The
Opaque
type is deprecated in favor ofTagged
.Attach a "tag" to an arbitrary type. This allows you to create distinct types, that aren't assignable to one another, for runtime values that would otherwise have the same type. (See examples.)
The generic type parameters can be anything.
Note that
Opaque
is somewhat of a misnomer here, in that, unlike [some alternative implementations](https://github.com/microsoft/TypeScript/issues/4895#issuecomment-425132582), the original, untagged type is not actually hidden. (E.g., functions that accept the untagged type can still be called with the "opaque" version -- but not vice-versa.)Also note that this implementation is limited to a single tag. If you want to allow multiple tags, use
Tagged
instead.[Read more about tagged types.](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d)
There have been several discussions about adding similar features to TypeScript. Unfortunately, nothing has (yet) moved forward: - [Microsoft/TypeScript#202](https://github.com/microsoft/TypeScript/issues/202) - [Microsoft/TypeScript#15408](https://github.com/Microsoft/TypeScript/issues/15408) - [Microsoft/TypeScript#15807](https://github.com/Microsoft/TypeScript/issues/15807)
Example 1
import type {Opaque} from 'type-fest';type AccountNumber = Opaque<number, 'AccountNumber'>;type AccountBalance = Opaque<number, 'AccountBalance'>;// The `Token` parameter allows the compiler to differentiate between types, whereas "unknown" will not. For example, consider the following structures:type ThingOne = Opaque<string>;type ThingTwo = Opaque<string>;// To the compiler, these types are allowed to be cast to each other as they have the same underlying type. They are both `string & { __opaque__: unknown }`.// To avoid this behaviour, you would instead pass the "Token" parameter, like so.type NewThingOne = Opaque<string, 'ThingOne'>;type NewThingTwo = Opaque<string, 'ThingTwo'>;// Now they're completely separate types, so the following will fail to compile.function createNewThingOne (): NewThingOne {// As you can see, casting from a string is still allowed. However, you may not cast NewThingOne to NewThingTwo, and vice versa.return 'new thing one' as NewThingOne;}// This will fail to compile, as they are fundamentally different types.const thingTwo = createNewThingOne() as NewThingTwo;// Here's another example of opaque typing.function createAccountNumber(): AccountNumber {return 2 as AccountNumber;}function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance {return 4 as AccountBalance;}// This will compile successfully.getMoneyForAccount(createAccountNumber());// But this won't, because it has to be explicitly passed as an `AccountNumber` type.getMoneyForAccount(2);// You can use opaque values like they aren't opaque too.const accountNumber = createAccountNumber();// This will compile successfully.const newAccountNumber = accountNumber + 2;// As a side note, you can (and should) use recursive types for your opaque types to make them stronger and hopefully easier to type.type Person = {id: Opaque<number, Person>;name: string;};Type
Deprecated
Use Tagged instead
type OptionalKeysOf
type OptionalKeysOf<BaseType extends object> = Exclude< { [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? never : Key; }[keyof BaseType], undefined>;
Extract all optional keys from the given type.
This is useful when you want to create a new type that contains different type values for the optional keys only.
Example 1
import type {OptionalKeysOf, Except} from 'type-fest';interface User {name: string;surname: string;luckyNumber?: number;}const REMOVE_FIELD = Symbol('remove field symbol');type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {[Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;};const update1: UpdateOperation<User> = {name: 'Alice'};const update2: UpdateOperation<User> = {name: 'Bob',luckyNumber: REMOVE_FIELD};Utilities
type Or
type Or<A extends boolean, B extends boolean> = [A, B][number] extends false ? false : true extends [IsEqual<A, true>, IsEqual<B, true>][number] ? true : never;
Returns a boolean for whether either of two given types are true.
Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
Example 1
import type {Or} from 'type-fest';Or<true, false>;//=> trueOr<false, false>;//=> falseSee Also
type OverrideProperties
type OverrideProperties< TOriginal, // This first bit where we use `Partial` is to enable autocomplete // and the second bit with the mapped type is what enforces that we don't try // to override properties that doesn't exist in the original type. TOverride extends Partial<Record<keyof TOriginal, unknown>> & { [Key in keyof TOverride]: Key extends keyof TOriginal ? TOverride[Key] : never; }> = Merge<TOriginal, TOverride>;
Override existing properties of the given type. Similar to
Merge
, but enforces that the original type has the properties you want to override.This is useful when you want to override existing properties with a different type and make sure that these properties really exist in the original.
Example 1
type Foo = {a: stringb: string}type Bar = OverrideProperties<Foo, {b: number}>//=> {a: string, b: number}type Baz = OverrideProperties<Foo, {c: number}>// Error, type '{ c: number; }' does not satisfy the constraint '{ c: never; }'type Fizz = OverrideProperties<Foo, {b: number; c: number}>// Error, type '{ b: number; c: number; }' does not satisfy the constraint '{ b: number; c: never; }'Object
type PackageJson
type PackageJson = JsonObject & PackageJson.NodeJsStandard & PackageJson.PackageJsonStandard & PackageJson.NonStandardEntryPoints & PackageJson.TypeScriptConfiguration & PackageJson.YarnConfiguration & PackageJson.JSPMConfiguration;
Type for [npm's
package.json
file](https://docs.npmjs.com/creating-a-package-json-file). Also includes types for fields used by other popular projects, like TypeScript and Yarn.File
type PartialDeep
type PartialDeep<T, Options extends PartialDeepOptions = {}> = T extends | BuiltIns | ((...arguments_: any[]) => unknown) | (new (...arguments_: any[]) => unknown) ? T : T extends Map<infer KeyType, infer ValueType> ? PartialMapDeep<KeyType, ValueType, Options> : T extends Set<infer ItemType> ? PartialSetDeep<ItemType, Options> : T extends ReadonlyMap<infer KeyType, infer ValueType> ? PartialReadonlyMapDeep<KeyType, ValueType, Options> : T extends ReadonlySet<infer ItemType> ? PartialReadonlySetDeep<ItemType, Options> : T extends object ? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 ? Options['recurseIntoArrays'] extends true ? ItemType[] extends T // Test for arrays (non-tuples) specifically ? readonly ItemType[] extends T // Differentiate readonly and mutable arrays ? ReadonlyArray<PartialDeep<ItemType | undefined, Options>> : Array<PartialDeep<ItemType | undefined, Options>> : PartialObjectDeep<T, Options> // Tuples behave properly : T // If they don't opt into array testing, just use the original type : PartialObjectDeep<T, Options> : unknown;
Create a type from another type with all keys and nested keys set to optional.
Use-cases: - Merging a default settings/config object with another object, the second object would be a deep partial of the default object. - Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test.
Example 1
import type {PartialDeep} from 'type-fest';const settings: Settings = {textEditor: {fontSize: 14;fontColor: '#000000';fontWeight: 400;}autocomplete: false;autosave: true;};const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {return {...settings, ...savedSettings};}settings = applySavedSettings({textEditor: {fontWeight: 500}});By default, this does not affect elements in array and tuple types. You can change this by passing
{recurseIntoArrays: true}
as the second type argument:import type {PartialDeep} from 'type-fest';interface Settings {languages: string[];}const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = {languages: [undefined]};Object Array Set Map
type PartialDeepOptions
type PartialDeepOptions = { /** Whether to affect the individual elements of arrays and tuples.
@default false */ readonly recurseIntoArrays?: boolean;};
See Also
PartialDeep
type PartialOnUndefinedDeep
type PartialOnUndefinedDeep< T, Options extends PartialOnUndefinedDeepOptions = {}> = T extends Record<any, any> | undefined ? { [KeyType in keyof T as undefined extends T[KeyType] ? IfUnknown<T[KeyType], never, KeyType> : never]?: PartialOnUndefinedDeepValue<T[KeyType], Options>; } extends infer U // Make a partial type with all value types accepting undefined (and set them optional) ? Merge< { [KeyType in keyof T as KeyType extends LiteralKeyOf<U> ? never : KeyType]: PartialOnUndefinedDeepValue<T[KeyType], Options>; }, U > // Join all remaining keys not treated in U : never // Should not happen : T;
Create a deep version of another type where all keys accepting
undefined
type are set to optional.This utility type is recursive, transforming at any level deep. By default, it does not affect arrays and tuples items unless you explicitly pass
{recurseIntoArrays: true}
as the second type argument.Use-cases: - Make all properties of a type that can be undefined optional to not have to specify keys with undefined value.
Example 1
import type {PartialOnUndefinedDeep} from 'type-fest';interface Settings {optionA: string;optionB: number | undefined;subOption: {subOptionA: boolean;subOptionB: boolean | undefined;}};const testSettings: PartialOnUndefinedDeep<Settings> = {optionA: 'foo',// 👉 optionB is now optional and can be omittedsubOption: {subOptionA: true,// 👉 subOptionB is now optional as well and can be omitted},};Object
type PartialOnUndefinedDeepOptions
type PartialOnUndefinedDeepOptions = { /** Whether to affect the individual elements of arrays and tuples.
@default false */ readonly recurseIntoArrays?: boolean;};
See Also
PartialOnUndefinedDeep
type PascalCase
type PascalCase< Value, Options extends CamelCaseOptions = { preserveConsecutiveUppercase: true }> = CamelCase<Value, Options> extends string ? Capitalize<CamelCase<Value, Options>> : CamelCase<Value, Options>;
Converts a string literal to pascal-case.
Example 1
import type {PascalCase} from 'type-fest';// Simpleconst someVariable: PascalCase<'foo-bar'> = 'FooBar';// Advancedtype PascalCaseProps<T> = {[K in keyof T as PascalCase<K>]: T[K]};interface RawOptions {'dry-run': boolean;'full_family_name': string;foo: number;}const dbResult: CamelCasedProperties<ModelProps> = {DryRun: true,FullFamilyName: 'bar.js',Foo: 123};Change case Template literal
type PascalCasedProperties
type PascalCasedProperties< Value, Options extends CamelCaseOptions = { preserveConsecutiveUppercase: true }> = Value extends Function ? Value : Value extends Array<infer U> ? Value : { [K in keyof Value as PascalCase<K, Options>]: Value[K] };
Convert object properties to pascal case but not recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {PascalCasedProperties} from 'type-fest';interface User {userId: number;userName: string;}const result: PascalCasedProperties<User> = {UserId: 1,UserName: 'Tom',};Change case Template literal Object
See Also
PascalCase
PascalCasedPropertiesDeep
type PascalCasedPropertiesDeep
type PascalCasedPropertiesDeep< Value, Options extends CamelCaseOptions = { preserveConsecutiveUppercase: true }> = Value extends Function | Date | RegExp ? Value : Value extends Array<infer U> ? Array<PascalCasedPropertiesDeep<U, Options>> : Value extends Set<infer U> ? Set<PascalCasedPropertiesDeep<U, Options>> : { [K in keyof Value as PascalCase<K, Options>]: PascalCasedPropertiesDeep< Value[K], Options >; };
Convert object properties to pascal case recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {PascalCasedPropertiesDeep} from 'type-fest';interface User {userId: number;userName: string;}interface UserWithFriends {userInfo: User;userFriends: User[];}const result: PascalCasedPropertiesDeep<UserWithFriends> = {UserInfo: {UserId: 1,UserName: 'Tom',},UserFriends: [{UserId: 2,UserName: 'Jerry',},{UserId: 3,UserName: 'Spike',},],};Change case Template literal Object
See Also
PascalCase
PascalCasedProperties
type Paths
type Paths<T, Options extends PathsOptions = {}> = _Paths< T, { // Set default maxRecursionDepth to 10 maxRecursionDepth: Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : DefaultPathsOptions['maxRecursionDepth']; // Set default bracketNotation to false bracketNotation: Options['bracketNotation'] extends boolean ? Options['bracketNotation'] : DefaultPathsOptions['bracketNotation']; }>;
Generate a union of all possible paths to properties in the given object.
It also works with arrays.
Use-case: You want a type-safe way to access deeply nested properties in an object.
Example 1
import type {Paths} from 'type-fest';type Project = {filename: string;listA: string[];listB: [{filename: string}];folder: {subfolder: {filename: string;};};};type ProjectPaths = Paths<Project>;//=> 'filename' | 'listA' | 'listB' | 'folder' | `listA.${number}` | 'listB.0' | 'listB.0.filename' | 'folder.subfolder' | 'folder.subfolder.filename'declare function open<Path extends ProjectPaths>(path: Path): void;open('filename'); // Passopen('folder.subfolder'); // Passopen('folder.subfolder.filename'); // Passopen('foo'); // TypeError// Also works with arraysopen('listA.1'); // Passopen('listB.0'); // Passopen('listB.1'); // TypeError. Because listB only has one element.Object Array
type PickDeep
type PickDeep<T, PathUnion extends Paths<T>> = T extends NonRecursiveType ? never : T extends UnknownArray ? UnionToIntersection< { [P in PathUnion]: InternalPickDeep<T, P>; }[PathUnion] > : T extends object ? Simplify< UnionToIntersection< { [P in PathUnion]: InternalPickDeep<T, P>; }[PathUnion] > > : never;
Pick properties from a deeply-nested object.
It supports recursing into arrays.
Use-case: Distill complex objects down to the components you need to target.
Example 1
import type {PickDeep, PartialDeep} from 'type-fest';type Configuration = {userConfig: {name: string;age: number;address: [{city1: string;street1: string;},{city2: string;street2: string;}]};otherConfig: any;};type NameConfig = PickDeep<Configuration, 'userConfig.name'>;// type NameConfig = {// userConfig: {// name: string;// }// };// Supports optional propertiestype User = PickDeep<PartialDeep<Configuration>, 'userConfig.name' | 'userConfig.age'>;// type User = {// userConfig?: {// name?: string;// age?: number;// };// };// Supports arraytype AddressConfig = PickDeep<Configuration, 'userConfig.address.0'>;// type AddressConfig = {// userConfig: {// address: [{// city1: string;// street1: string;// }];// };// }// Supports recurse into arraytype Street = PickDeep<Configuration, 'userConfig.address.1.street2'>;// type Street = {// userConfig: {// address: [// unknown,// {street2: string}// ];// };// }Object Array
type PickIndexSignature
type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType];};
Pick only index signatures from the given object type, leaving out all explicitly defined properties.
This is the counterpart of
OmitIndexSignature
.When you use a type that will iterate through an object that has indexed keys and explicitly defined keys you end up with a type where only the indexed keys are kept. This is because
keyof
of an indexed type always returnsstring | number | symbol
, because every key is possible in that object. With this type, you can save the indexed keys and reinject them later, like in the second example below.Example 1
import type {PickIndexSignature} from 'type-fest';declare const symbolKey: unique symbol;type Example = {// These index signatures will remain.[x: string]: unknown;[x: number]: unknown;[x: symbol]: unknown;[x: `head-${string}`]: string;[x: `${string}-tail`]: string;[x: `head-${string}-tail`]: string;[x: `${bigint}`]: string;[x: `embedded-${number}`]: string;// These explicitly defined keys will be removed.['snake-case-key']: string;[symbolKey]: string;foo: 'bar';qux?: 'baz';};type ExampleIndexSignature = PickIndexSignature<Example>;// {// [x: string]: unknown;// [x: number]: unknown;// [x: symbol]: unknown;// [x: `head-${string}`]: string;// [x: `${string}-tail`]: string;// [x: `head-${string}-tail`]: string;// [x: `${bigint}`]: string;// [x: `embedded-${number}`]: string;// }Example 2
import type {OmitIndexSignature, PickIndexSignature, Simplify} from 'type-fest';type Foo = {[x: string]: string;foo: string;bar: number;};// Imagine that you want a new type `Bar` that comes from `Foo`.// => {// [x: string]: string;// bar: number;// };type Bar = Omit<Foo, 'foo'>;// This is not working because `Omit` returns only indexed keys.// => {// [x: string]: string;// [x: number]: string;// }// One solution is to save the indexed signatures to new type.type FooIndexSignature = PickIndexSignature<Foo>;// => {// [x: string]: string;// }// Get a new type without index signatures.type FooWithoutIndexSignature = OmitIndexSignature<Foo>;// => {// foo: string;// bar: number;// }// At this point we can use Omit to get our new type.type BarWithoutIndexSignature = Omit<FooWithoutIndexSignature, 'foo'>;// => {// bar: number;// }// And finally we can merge back the indexed signatures.type BarWithIndexSignature = Simplify<BarWithoutIndexSignature & FooIndexSignature>;// => {// [x: string]: string;// bar: number;// }See Also
OmitIndexSignature Object
type PositiveInfinity
type PositiveInfinity = 1e999;
Matches the hidden
Infinity
type.Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
See Also
NegativeInfinity
Numeric
type Primitive
type Primitive = null | undefined | string | number | boolean | symbol | bigint;
Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
Type
type Promisable
type Promisable<T> = T | PromiseLike<T>;
Create a type that represents either the value or the value wrapped in
PromiseLike
.Use-cases: - A function accepts a callback that may either return a value synchronously or may return a promised value. - This type could be the return type of
Promise#then()
,Promise#catch()
, andPromise#finally()
callbacks.Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31394) if you want to have this type as a built-in in TypeScript.
Example 1
import type {Promisable} from 'type-fest';async function logger(getLogEntry: () => Promisable<string>): Promise<void> {const entry = await getLogEntry();console.log(entry);}logger(() => 'foo');logger(() => Promise.resolve('bar'));Async
type ReadonlyDeep
type ReadonlyDeep<T> = T extends BuiltIns ? T : T extends new (...arguments_: any[]) => unknown ? T // Skip class constructors : T extends (...arguments_: any[]) => unknown ? {} extends ReadonlyObjectDeep<T> ? T : HasMultipleCallSignatures<T> extends true ? T : ((...arguments_: Parameters<T>) => ReturnType<T>) & ReadonlyObjectDeep<T> : T extends Readonly<ReadonlyMap<infer KeyType, infer ValueType>> ? ReadonlyMapDeep<KeyType, ValueType> : T extends Readonly<ReadonlySet<infer ItemType>> ? ReadonlySetDeep<ItemType> : // Identify tuples to avoid converting them to arrays inadvertently; special case `readonly [...never[]]`, as it emerges undesirably from recursive invocations of ReadonlyDeep below. T extends readonly [] | readonly [...never[]] ? readonly [] : T extends readonly [infer U, ...infer V] ? readonly [ReadonlyDeep<U>, ...ReadonlyDeep<V>] : T extends readonly [...infer U, infer V] ? readonly [...ReadonlyDeep<U>, ReadonlyDeep<V>] : T extends ReadonlyArray<infer ItemType> ? ReadonlyArray<ReadonlyDeep<ItemType>> : T extends object ? ReadonlyObjectDeep<T> : unknown;
Convert
object
s,Map
s,Set
s, andArray
s and all of their keys/elements into immutable structures recursively.This is useful when a deeply nested structure needs to be exposed as completely immutable, for example, an imported JSON module or when receiving an API response that is passed around.
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/13923) if you want to have this type as a built-in in TypeScript.
Example 1
// data.json{"foo": ["bar"]}// main.tsimport type {ReadonlyDeep} from 'type-fest';import dataJson = require('./data.json');const data: ReadonlyDeep<typeof dataJson> = dataJson;export default data;// test.tsimport data from './main';data.foo.push('bar');//=> error TS2339: Property 'push' does not exist on type 'readonly string[]'Note that types containing overloaded functions are not made deeply readonly due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
Object Array Set Map
type ReadonlyKeysOf
type ReadonlyKeysOf<T> = NonNullable< { [P in keyof T]: IsEqual< { [Q in P]: T[P] }, { readonly [Q in P]: T[P] } > extends true ? P : never; }[keyof T]>;
Extract all readonly keys from the given type.
This is useful when you want to create a new type that contains readonly keys only.
Example 1
import type {ReadonlyKeysOf} from 'type-fest';interface User {name: string;surname: string;readonly id: number;}type UpdateResponse<Entity extends object> = Pick<Entity, ReadonlyKeysOf<Entity>>;const update1: UpdateResponse<User> = {id: 123,};Utilities
type ReadonlyTuple
type ReadonlyTuple<Element, Length extends number> = number extends Length ? // Because `Length extends number` and `number extends Length`, then `Length` is not a specific finite number. readonly Element[] // It's not fixed length. : BuildTupleHelper<Element, Length, []>;
Create a type that represents a read-only tuple of the given type and length.
Use-cases: - Declaring fixed-length tuples with a large number of items. - Creating a range union (for example,
0 | 1 | 2 | 3 | 4
from the keys of such a type) without having to resort to recursive types. - Creating a tuple of coordinates with a static length, for example, length of 3 for a 3D vector.Example 1
import {ReadonlyTuple} from 'type-fest';type FencingTeam = ReadonlyTuple<string, 3>;const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert'];const homeFencingTeam: FencingTeam = ['George', 'John'];//=> error TS2322: Type string[] is not assignable to type 'FencingTeam'guestFencingTeam.push('Sam');//=> error TS2339: Property 'push' does not exist on type 'FencingTeam'Utilities
type Replace
type Replace< Input extends string, Search extends string, Replacement extends string, Options extends ReplaceOptions = {}> = Input extends `${infer Head}${Search}${infer Tail}` ? Options['all'] extends true ? `${Head}${Replacement}${Replace<Tail, Search, Replacement, Options>}` : `${Head}${Replacement}${Tail}` : Input;
Represents a string with some or all matches replaced by a replacement.
Use-case: -
snake-case-path
todotted.path.notation
- Changing date/time format:01-08-2042
→01/08/2042
- Manipulation of type properties, for example, removal of prefixesExample 1
import {Replace} from 'type-fest';declare function replace<Input extends string,Search extends string,Replacement extends string>(input: Input,search: Search,replacement: Replacement): Replace<Input, Search, Replacement>;declare function replaceAll<Input extends string,Search extends string,Replacement extends string>(input: Input,search: Search,replacement: Replacement): Replace<Input, Search, Replacement, {all: true}>;// The return type is the exact string literal, not just `string`.replace('hello ?', '?', '🦄');//=> 'hello 🦄'replace('hello ??', '?', '❓');//=> 'hello ❓?'replaceAll('10:42:00', ':', '-');//=> '10-42-00'replaceAll('__userName__', '__', '');//=> 'userName'replaceAll('My Cool Title', ' ', '');//=> 'MyCoolTitle'String Template literal
type RequireAllOrNone
type RequireAllOrNone< ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> = (RequireAll<ObjectType, KeysType> | RequireNone<KeysType>) & Omit<ObjectType, KeysType>;
Create a type that requires all of the given keys or none of the given keys. The remaining keys are kept as is.
Use-cases: - Creating interfaces for components with mutually-inclusive keys.
The caveat with
RequireAllOrNone
is that TypeScript doesn't always know at compile time every key that will exist at runtime. ThereforeRequireAllOrNone
can't do anything to prevent extra keys it doesn't know about.Example 1
import type {RequireAllOrNone} from 'type-fest';type Responder = {text?: () => string;json?: () => string;secure: boolean;};const responder1: RequireAllOrNone<Responder, 'text' | 'json'> = {secure: true};const responder2: RequireAllOrNone<Responder, 'text' | 'json'> = {text: () => '{"message": "hi"}',json: () => '{"message": "ok"}',secure: true};Object
type RequireAtLeastOne
type RequireAtLeastOne< ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> = { // For each `Key` in `KeysType` make a mapped type: [Key in KeysType]-?: Required<Pick<ObjectType, Key>> & // 1. Make `Key`'s type required // 2. Make all other keys in `KeysType` optional Partial<Pick<ObjectType, Exclude<KeysType, Key>>>;}[KeysType] & // 3. Add the remaining keys not in `KeysType` Except<ObjectType, KeysType>;
Create a type that requires at least one of the given keys. The remaining keys are kept as is.
Example 1
import type {RequireAtLeastOne} from 'type-fest';type Responder = {text?: () => string;json?: () => string;secure?: boolean;};const responder: RequireAtLeastOne<Responder, 'text' | 'json'> = {json: () => '{"message": "ok"}',secure: true};Object
type RequiredDeep
type RequiredDeep< T, E extends ExcludeUndefined<T> = ExcludeUndefined<T>> = E extends BuiltIns ? E : E extends Map<infer KeyType, infer ValueType> ? Map<RequiredDeep<KeyType>, RequiredDeep<ValueType>> : E extends Set<infer ItemType> ? Set<RequiredDeep<ItemType>> : E extends ReadonlyMap<infer KeyType, infer ValueType> ? ReadonlyMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>> : E extends ReadonlySet<infer ItemType> ? ReadonlySet<RequiredDeep<ItemType>> : E extends WeakMap<infer KeyType, infer ValueType> ? WeakMap<RequiredDeep<KeyType>, RequiredDeep<ValueType>> : E extends WeakSet<infer ItemType> ? WeakSet<RequiredDeep<ItemType>> : E extends Promise<infer ValueType> ? Promise<RequiredDeep<ValueType>> : E extends (...arguments_: any[]) => unknown ? {} extends RequiredObjectDeep<E> ? E : HasMultipleCallSignatures<E> extends true ? E : ((...arguments_: Parameters<E>) => ReturnType<E>) & RequiredObjectDeep<E> : E extends object ? E extends Array<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 ? ItemType[] extends E // Test for arrays (non-tuples) specifically ? Array<RequiredDeep<ItemType>> // Recreate relevant array type to prevent eager evaluation of circular reference : RequiredObjectDeep<E> // Tuples behave properly : RequiredObjectDeep<E> : unknown;
Create a type from another type with all keys and nested keys set to required.
Use-cases: - Creating optional configuration interfaces where the underlying implementation still requires all options to be fully specified. - Modeling the resulting type after a deep merge with a set of defaults.
Example 1
import type {RequiredDeep} from 'type-fest';type Settings = {textEditor?: {fontSize?: number | undefined;fontColor?: string | undefined;fontWeight?: number | undefined;}autocomplete?: boolean | undefined;autosave?: boolean | undefined;};type RequiredSettings = RequiredDeep<Settings>;// type RequiredSettings = {// textEditor: {// fontSize: number;// fontColor: string;// fontWeight: number;// }// autocomplete: boolean;// autosave: boolean;// }Note that types containing overloaded functions are not made deeply required due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
Utilities Object Array Set Map
type RequiredKeysOf
type RequiredKeysOf<BaseType extends object> = Exclude< { [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never; }[keyof BaseType], undefined>;
Extract all required keys from the given type.
This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc...
Example 1
import type {RequiredKeysOf} from 'type-fest';declare function createValidation<Entity extends object, Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>>(field: Key, validator: (value: Entity[Key]) => boolean): ValidatorFn;interface User {name: string;surname: string;luckyNumber?: number;}const validator1 = createValidation<User>('name', value => value.length < 25);const validator2 = createValidation<User>('surname', value => value.length < 25);Utilities
type RequireExactlyOne
type RequireExactlyOne< ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> = { [Key in KeysType]: Required<Pick<ObjectType, Key>> & Partial<Record<Exclude<KeysType, Key>, never>>;}[KeysType] & Omit<ObjectType, KeysType>;
Create a type that requires exactly one of the given keys and disallows more. The remaining keys are kept as is.
Use-cases: - Creating interfaces for components that only need one of the keys to display properly. - Declaring generic keys in a single place for a single use-case that gets narrowed down via
RequireExactlyOne
.The caveat with
RequireExactlyOne
is that TypeScript doesn't always know at compile time every key that will exist at runtime. ThereforeRequireExactlyOne
can't do anything to prevent extra keys it doesn't know about.Example 1
import type {RequireExactlyOne} from 'type-fest';type Responder = {text: () => string;json: () => string;secure: boolean;};const responder: RequireExactlyOne<Responder, 'text' | 'json'> = {// Adding a `text` key here would cause a compile error.json: () => '{"message": "ok"}',secure: true};Object
type RequireOneOrNone
type RequireOneOrNone< ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> = (RequireExactlyOne<ObjectType, KeysType> | RequireNone<KeysType>) & Omit<ObjectType, KeysType>;
Create a type that requires exactly one of the given keys and disallows more, or none of the given keys. The remaining keys are kept as is.
Example 1
import type {RequireOneOrNone} from 'type-fest';type Responder = RequireOneOrNone<{text: () => string;json: () => string;secure: boolean;}, 'text' | 'json'>;const responder1: Responder = {secure: true};const responder2: Responder = {text: () => '{"message": "hi"}',secure: true};const responder3: Responder = {json: () => '{"message": "ok"}',secure: true};Object
type Schema
type Schema<ObjectType, ValueType> = ObjectType extends string ? ValueType : ObjectType extends Map<unknown, unknown> ? ValueType : ObjectType extends Set<unknown> ? ValueType : ObjectType extends ReadonlyMap<unknown, unknown> ? ValueType : ObjectType extends ReadonlySet<unknown> ? ValueType : ObjectType extends Array<infer U> ? Array<Schema<U, ValueType>> : ObjectType extends (...arguments_: unknown[]) => unknown ? ValueType : ObjectType extends Date ? ValueType : ObjectType extends Function ? ValueType : ObjectType extends RegExp ? ValueType : ObjectType extends object ? SchemaObject<ObjectType, ValueType> : ValueType;
Create a deep version of another object type where property values are recursively replaced into a given value type.
Use-cases: - Form validation: Define how each field should be validated. - Form settings: Define configuration for input fields. - Parsing: Define types that specify special behavior for specific fields.
Example 1
import type {Schema} from 'type-fest';interface User {id: string;name: {firstname: string;lastname: string;};created: Date;active: boolean;passwordHash: string;}type UserMask = Schema<User, 'mask' | 'hide' | 'show'>;const userMaskSettings: UserMask = {id: 'show',name: {firstname: 'show',lastname: 'mask',},created: 'show',active: 'show',passwordHash: 'hide',}Object
type ScreamingSnakeCase
type ScreamingSnakeCase<Value> = Value extends string ? IsScreamingSnakeCase<Value> extends true ? Value : Uppercase<SnakeCase<Value>> : Value;
Convert a string literal to screaming-snake-case.
This can be useful when, for example, converting a camel-cased object property to a screaming-snake-cased SQL column name.
Example 1
import type {ScreamingSnakeCase} from 'type-fest';const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR';Change case Template literal
type SetFieldType
type SetFieldType<BaseType, Keys extends keyof BaseType, NewType> = Simplify< Except<BaseType, Keys> & Record<Keys, NewType>>;
Create a type that changes the type of the given keys.
Use-cases: - Creating variations of a base model. - Fixing incorrect external types.
Example 1
import type {SetFieldType} from 'type-fest';type MyModel = {id: number;createdAt: Date;updatedAt: Date;};type MyModelApi = SetFieldType<MyModel, 'createdAt' | 'updatedAt', string>;// {// id: number;// createdAt: string;// updatedAt: string;// }Object
See Also
Merge
if you need to change multiple properties to different types.
type SetNonNullable
type SetNonNullable<BaseType, Keys extends keyof BaseType = keyof BaseType> = { [Key in keyof BaseType]: Key extends Keys ? NonNullable<BaseType[Key]> : BaseType[Key];};
Create a type that makes the given keys non-nullable, where the remaining keys are kept as is.
If no keys are given, all keys will be made non-nullable.
Use-case: You want to define a single model where the only thing that changes is whether or not some or all of the keys are non-nullable.
Example 1
import type {SetNonNullable} from 'type-fest';type Foo = {a: number | null;b: string | undefined;c?: boolean | null;}type SomeNonNullable = SetNonNullable<Foo, 'b' | 'c'>;// type SomeNonNullable = {// a: number | null;// b: string; // Can no longer be undefined.// c?: boolean; // Can no longer be null, but is still optional.// }type AllNonNullable = SetNonNullable<Foo>;// type AllNonNullable = {// a: number; // Can no longer be null.// b: string; // Can no longer be undefined.// c?: boolean; // Can no longer be null, but is still optional.// }Object
type SetOptional
type SetOptional<BaseType, Keys extends keyof BaseType> = Simplify< // Pick just the keys that are readonly from the base type. Except<BaseType, Keys> & // Pick the keys that should be mutable from the base type and make them mutable. Partial<Pick<BaseType, Keys>>>;
Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the
SetRequired
type.Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional.
Example 1
import type {SetOptional} from 'type-fest';type Foo = {a: number;b?: string;c: boolean;}type SomeOptional = SetOptional<Foo, 'b' | 'c'>;// type SomeOptional = {// a: number;// b?: string; // Was already optional and still is.// c?: boolean; // Is now optional.// }Object
type SetParameterType
type SetParameterType< Function_ extends (...arguments_: any[]) => unknown, P extends Record<number, unknown>> = // Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter. Function_ extends ( this: infer ThisArgument, ...arguments_: infer Arguments ) => unknown ? // If a function did not specify the `this` fake parameter, it will be inferred to `unknown`. // We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE. IsUnknown<ThisArgument> extends true ? ( ...arguments_: MergeObjectToArray<Arguments, P> ) => ReturnType<Function_> : ( this: ThisArgument, ...arguments_: MergeObjectToArray<Arguments, P> ) => ReturnType<Function_> : Function_;
Create a function that replaces some parameters with the given parameters.
The parameters that are not specified will be kept as-is.
Note: - This type will ignore the given function's generic type. - If you change the parameter type that return type depends on, the return type will not change: ``` const fn = (a: number) => a; //=> fn: (a: number) => number;
// We change type of
a
tostring
, but return type is stillnumber
. type Fn = SetParameterType<typeof fn, {0: string}>; //=> (a: string) => number; ```Use-case: - Define a wrapped function that receives something different while returning the same type. - Mocking and testing. - Overload function type. (See example)
Example 1
import type {SetParameterType} from 'type-fest';type HandleMessage = (data: Data, message: string, ...arguments: any[]) => void;type HandleOk = SetParameterType<HandleMessage, {0: SuccessData, 1: 'ok'}>;//=> type HandleOk = (data: SuccessData, message: 'ok') => void;// Another way to define the parameters to replace.type HandleError = SetParameterType<HandleMessage, [data: ErrorData, message: 'error']>;//=> type HandleError = (data: ErrorData, message: 'error') => void;// Change single parameter type.type HandleWarn = SetParameterType<HandleMessage, {1: 'warn'}>;//=> type HandleWarn = (data: Data, message: 'warn') => void;// Change rest parameter type.// Way 1: Input full parameter type.type HandleLog = SetParameterType<HandleMessage, [data: Data, message: 'log', ...arguments: string[]]>;//=> type HandleLog = (data: Data, message: 'log', ...arguments: string[]) => void;// Way 2: Input rest parameter type by Object index.type HandleLog2 = SetParameterType<HandleMessage, {2: string}>;//=> type HandleLog2 = (data: Data, message: string, ...arguments: string[]) => void;Function
type SetReadonly
type SetReadonly<BaseType, Keys extends keyof BaseType> = // `extends unknown` is always going to be the case and is used to convert any // union into a [distributive conditional // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). BaseType extends unknown ? Simplify<Except<BaseType, Keys> & Readonly<Pick<BaseType, Keys>>> : never;
Create a type that makes the given keys readonly. The remaining keys are kept as is.
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are readonly.
Example 1
import type {SetReadonly} from 'type-fest';type Foo = {a: number;readonly b: string;c: boolean;}type SomeReadonly = SetReadonly<Foo, 'b' | 'c'>;// type SomeReadonly = {// a: number;// readonly b: string; // Was already readonly and still is.// readonly c: boolean; // Is now readonly.// }Object
type SetRequired
type SetRequired<BaseType, Keys extends keyof BaseType> = // `extends unknown` is always going to be the case and is used to convert any // union into a [distributive conditional // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). BaseType extends unknown ? Simplify< // Pick just the keys that are optional from the base type. Except<BaseType, Keys> & // Pick the keys that should be required from the base type and make them required. Required<Pick<BaseType, Keys>> > : never;
Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the
SetOptional
type.Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.
Example 1
import type {SetRequired} from 'type-fest';type Foo = {a?: number;b: string;c?: boolean;}type SomeRequired = SetRequired<Foo, 'b' | 'c'>;// type SomeRequired = {// a?: number;// b: string; // Was already required and still is.// c: boolean; // Is now required.// }Object
type SetReturnType
type SetReturnType<Function_ extends (...arguments_: any[]) => any, TypeToReturn> = // Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter. Function_ extends ( this: infer ThisArgument, ...arguments_: infer Arguments ) => any ? // If a function did not specify the `this` fake parameter, it will be inferred to `unknown`. // We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE. IsUnknown<ThisArgument> extends true ? (...arguments_: Arguments) => TypeToReturn : (this: ThisArgument, ...arguments_: Arguments) => TypeToReturn : // This part should be unreachable, but we make it meaningful just in case… (...arguments_: Parameters<Function_>) => TypeToReturn;
Create a function type with a return type of your choice and the same parameters as the given function type.
Use-case: You want to define a wrapped function that returns something different while receiving the same parameters. For example, you might want to wrap a function that can throw an error into one that will return
undefined
instead.Example 1
import type {SetReturnType} from 'type-fest';type MyFunctionThatCanThrow = (foo: SomeType, bar: unknown) => SomeOtherType;type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | undefined>;//=> type MyWrappedFunction = (foo: SomeType, bar: unknown) => SomeOtherType | undefined;Function
type SharedUnionFieldsDeep
type SharedUnionFieldsDeep< Union, Options extends SharedUnionFieldsDeepOptions = { recurseIntoArrays: false }> = // If `Union` is not a union type, return `Union` directly. IsUnion<Union> extends false ? Union : // `Union extends` will convert `Union` // to a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). // But this is not what we want, so we need to wrap `Union` with `[]` to prevent it. [Union] extends [ NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> ] ? Union : [Union] extends [UnknownArray] ? Options['recurseIntoArrays'] extends true ? SetArrayAccess< SharedArrayUnionFieldsDeep<Union, Options>, IsArrayReadonly<Union> > : Union : [Union] extends [object] ? SharedObjectUnionFieldsDeep<Union, Options> : Union;
Create a type with shared fields from a union of object types, deeply traversing nested structures.
Use the to specify the behavior for arrays.
Use-cases: - You want a safe object type where each key exists in the union object. - You want to focus on the common fields of the union type and don't want to have to care about the other fields.
Example 1
import type {SharedUnionFieldsDeep} from 'type-fest';type Cat = {info: {name: string;type: 'cat';catType: string;};};type Dog = {info: {name: string;type: 'dog';dogType: string;};};function displayPetInfo(petInfo: (Cat | Dog)['info']) {// typeof petInfo =>// {// name: string;// type: 'cat';// catType: string; // Needn't care about this field, because it's not a common pet info field.// } | {// name: string;// type: 'dog';// dogType: string; // Needn't care about this field, because it's not a common pet info field.// }// petInfo type is complex and have some needless fieldsconsole.log('name: ', petInfo.name);console.log('type: ', petInfo.type);}function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {// typeof petInfo =>// {// name: string;// type: 'cat' | 'dog';// }// petInfo type is simple and clearconsole.log('name: ', petInfo.name);console.log('type: ', petInfo.type);}Object Union
type Simplify
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
Example 1
import type {Simplify} from 'type-fest';type PositionProps = {top: number;left: number;};type SizeProps = {width: number;height: number;};// In your editor, hovering over `Props` will show a flattened object with all the properties.type Props = Simplify<PositionProps & SizeProps>;Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the
value
's type definition was defined as an interface. In the following example,fn
requires an argument of typeRecord<string, unknown>
. If the value is defined as a literal, then it is assignable. And if thevalue
is defined as type using theSimplify
utility the value is assignable. But if thevalue
is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the
value
can be defined asconst value: Simplify<SomeInterface> = ...
. Thenvalue
will be assignable to thefn
argument. Or thevalue
can be cast asSimplify<SomeInterface>
if you can't re-declare thevalue
.Example 2
import type {Simplify} from 'type-fest';interface SomeInterface {foo: number;bar?: string;baz: number | undefined;}type SomeType = {foo: number;bar?: string;baz: number | undefined;};const literal = {foo: 123, bar: 'hello', baz: 456};const someType: SomeType = literal;const someInterface: SomeInterface = literal;function fn(object: Record<string, unknown>): void {}fn(literal); // Good: literal object type is sealedfn(someType); // Good: type is sealedfn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-openedfn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`https://github.com/microsoft/TypeScript/issues/15300
See Also
SimplifyDeep Object
type SimplifyDeep
type SimplifyDeep<Type, ExcludeType = never> = ConditionalSimplifyDeep< Type, ExcludeType | NonRecursiveType | Set<unknown> | Map<unknown, unknown>, object>;
Deeply simplifies an object type.
You can exclude certain types from being simplified by providing them in the second generic
ExcludeType
.Useful to flatten the type output to improve type hints shown in editors.
Example 1
import type {SimplifyDeep} from 'type-fest';type PositionX = {left: number;right: number;};type PositionY = {top: number;bottom: number;};type Properties1 = {height: number;position: PositionY;};type Properties2 = {width: number;position: PositionX;};type Properties = Properties1 & Properties2;// In your editor, hovering over `Props` will show the following://// type Properties = Properties1 & Properties2;type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2>;// But if wrapped in SimplifyDeep, hovering over `SimplifyDeepProperties` will show a flattened object with all the properties://// SimplifyDeepProperties = {// height: number;// width: number;// position: {// top: number;// bottom: number;// left: number;// right: number;// };// };Example 2
import type {SimplifyDeep} from 'type-fest';// A complex type that you don't want or need to simplifytype ComplexType = {a: string;b: 'b';c: number;...};type PositionX = {left: number;right: number;};type PositionY = {top: number;bottom: number;};// You want to simplify all other typestype Properties1 = {height: number;position: PositionY;foo: ComplexType;};type Properties2 = {width: number;position: PositionX;foo: ComplexType;};type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2, ComplexType>;// If wrapped in `SimplifyDeep` and set `ComplexType` to exclude, hovering over `SimplifyDeepProperties` will// show a flattened object with all the properties except `ComplexType`://// SimplifyDeepProperties = {// height: number;// width: number;// position: {// top: number;// bottom: number;// left: number;// right: number;// };// foo: ComplexType;// };See Also
Simplify Object
type SingleKeyObject
type SingleKeyObject<ObjectType> = IsUnion<keyof ObjectType> extends true ? never : IfEmptyObject<ObjectType, never, ObjectType>;
Create a type that only accepts an object with a single key.
Example 1
import type {SingleKeyObject} from 'type-fest';const someFunction = <T>(parameter: SingleKeyObject<T>) => {};someFunction({value: true});someFunction({value: true,otherKey: true});// Error: Argument of type '{value: boolean; otherKey: boolean}' is not assignable to parameter of type 'never'.ts(2345)Object
type SnakeCase
type SnakeCase<Value> = DelimiterCase<Value, '_'>;
Convert a string literal to snake-case.
This can be useful when, for example, converting a camel-cased object property to a snake-cased SQL column name.
Example 1
import type {SnakeCase} from 'type-fest';// Simpleconst someVariable: SnakeCase<'fooBar'> = 'foo_bar';// Advancedtype SnakeCasedProperties<T> = {[K in keyof T as SnakeCase<K>]: T[K]};interface ModelProps {isHappy: boolean;fullFamilyName: string;foo: number;}const dbResult: SnakeCasedProperties<ModelProps> = {'is_happy': true,'full_family_name': 'Carla Smith',foo: 123};Change case Template literal
type SnakeCasedProperties
type SnakeCasedProperties<Value> = DelimiterCasedProperties<Value, '_'>;
Convert object properties to snake case but not recursively.
This can be useful when, for example, converting some API types from a different style.
Example 1
import type {SnakeCasedProperties} from 'type-fest';interface User {userId: number;userName: string;}const result: SnakeCasedProperties<User> = {user_id: 1,user_name: 'Tom',};Change case Template literal Object
See Also
SnakeCase
SnakeCa