declare const __brand: unique symbol interface Brand { [__brand]: B } /** * Helper to create "Branded" types. * * Example: * export type MyId = Branded * * MyId can be assigned to a string, * but string cannot be assigned to MyId without casting it (`as MyId`). */ export type Branded = T & Brand /** * Map from String to String (or ). * * Alternative: Record */ export interface StringMap { [k: string | number]: T | undefined } /** * Convenience shorthand for `Record`. * Because `object` type is not safe/recommended to be used (e.g discouraged by eslint-typescript due to: https://github.com/microsoft/TypeScript/issues/21732) */ export type AnyObject = Record export type AnyEnum = NumberEnum export type NumberEnum = Record export type StringEnum = Record // oxlint-disable-next-line @typescript-eslint/consistent-type-definitions export type CreatedUpdated = { created: UnixTimestamp updated: UnixTimestamp } export interface CreatedUpdatedId extends CreatedUpdated { id: string } // oxlint-disable-next-line @typescript-eslint/consistent-type-definitions export type ObjectWithId = { id: string } // oxlint-disable-next-line @typescript-eslint/consistent-type-definitions export type PartialObjectWithId = { id?: string } export interface AnyPartialObjectWithId extends AnyObject, PartialObjectWithId {} export interface AnyObjectWithId extends AnyObject, ObjectWithId {} /** * Base interface for any Entity that was saved to DB. */ // oxlint-disable-next-line @typescript-eslint/consistent-type-definitions export type BaseDBEntity = { id: string /** * unixTimestamp of when the entity was first created (in the DB). */ created: UnixTimestamp /** * unixTimestamp of when the entity was last updated (in the DB). */ updated: UnixTimestamp } export type Saved = T & { id: string created: UnixTimestamp updated: UnixTimestamp } export type SavedId = T & { id: string } export type Unsaved = Omit & { id?: string created?: UnixTimestamp updated?: UnixTimestamp } export type UnsavedId = Omit & { id?: string } /** * Convenience type shorthand. * Because `Function` type is discouraged by eslint. */ export type AnyFunction = (...args: any[]) => T export type AnyAsyncFunction = (...args: any[]) => Promise export type AsyncFunction = () => Promise export type AnyPromisableFunction = (...args: any[]) => Promisable export type PromisableFunction = () => Promisable export type AnySyncFunction = (...args: any[]) => NotPromise export type SyncFunction = () => NotPromise /** * Compile-time guard against accidentally returning a Promise from a sync context. * Example usage: `fn: () => NotPromise` * This would fail if fn returns a Promise (e.g an async function). */ export type NotPromise = [T] extends [PromiseLike] ? never : T /** * A function that lazily calculates something. */ export type Lazy = () => T /** * A function that lazily calculates something async (returns a Promise). */ export type LazyPromise = () => Promise /** * A function that lazily calculates something async, that can return null. */ export type LazyNullablePromise = () => Promise /** * Evaluates to the parameters if T is a function, otherwise never */ export type MaybeParameters = FN extends AnyFunction ? Parameters : never /** * Symbol to indicate END of Sequence. */ export const END = Symbol('END') /** * Symbol to indicate SKIP of item (e.g in AbortableMapper) */ export const SKIP = Symbol('SKIP') /** * Symbol to indicate cache miss. * To distinguish from cache returning `undefined` or `null`. */ export const MISS = Symbol('MISS') /** * Function which is called for every item in `input`. Expected to return a `Promise`. */ export type AsyncMapper = (input: IN) => PromiseLike export type AsyncIndexedMapper = (input: IN, index: number) => PromiseLike export type Mapper = (input: IN) => OUT export type IndexedMapper = (input: IN, index: number) => OUT export const _passthroughMapper: IndexedMapper = item => item export const _passUndefinedMapper: IndexedMapper = () => undefined /** * Function that does nothings and returns `undefined`. */ export const _noop = (..._args: any[]): undefined => undefined export type Predicate = (item: T, index: number) => boolean export type AsyncPredicate = (item: T, index: number) => PromiseLike export type AbortablePredicate = (item: T, i: number) => boolean | typeof END export type AbortableAsyncPredicate = (item: T, i: number) => PromiseLike export type AbortableMapper = ( input: IN, i: number, ) => OUT | typeof SKIP | typeof END export type AbortableAsyncMapper = ( input: IN, i: number, ) => PromiseLike export const _passthroughPredicate: Predicate = () => true export const _passNothingPredicate: Predicate = () => false export interface BatchResult { /** * Array of successful executions. */ results: RES[] /** * Returns empty array in case of 0 errors. */ errors: ERR[] } /** * Like `keyof`, but for arrays. * * Based on: https://github.com/Microsoft/TypeScript/issues/20965#issuecomment-354858633 * * @example * * const arr = ['a', 'b'] as const * type Foo = ValuesOf // 'a' | 'b' */ export type ValuesOf = T[number] /** * Based on: https://stackoverflow.com/a/49286056/4919972 * * @example * * type Foo = { a: string, b: number } * type ValueOfFoo = ValueOf // string | number */ export type ValueOf = T[keyof T] export type KeyValueTuple = [key: K, value: V] // Exclude is used here to support StringMap (because values of StringMap add `undefined`) export type ObjectMapper = ( key: keyof OBJ, value: Exclude, obj: OBJ, ) => OUT export type ObjectPredicate = ( key: keyof OBJ, value: Exclude, obj: OBJ, ) => boolean /** * Allows to identify instance of Class by `instanceId`. */ export interface InstanceId { /** * Unique id of this instance of the Class. */ instanceId: string } /** * ISO 8601 date (without time). * Branded type. * * @example '2019-06-21' */ export type IsoDate = Branded /** * ISO 8601 date (date+time). * Branded type. * * @example '2019-06-21T05:21:73Z' */ export type IsoDateTime = Branded /** * ISO 8601 month (YYYY-MM). * Branded type. * * @example '2019-06' */ export type IsoMonth = Branded /** * Identifies IANA timezone name. * Branded type. * * @example 'America/New_York' */ export type IANATimezone = Branded /** * Branded UnixTimestamp in seconds. * Extends (compatible with) `number`. * * @example 1628945450 */ export type UnixTimestamp = Branded /** * Branded UnixTimestamp in milliseconds (not seconds). * Extends (compatible with) `number`. * * @example 1628945450000 */ export type UnixTimestampMillis = Branded export type NumberOfHours = number export type NumberOfMinutes = number export type NumberOfSeconds = number export type NumberOfMilliseconds = number /** * Integer between 0 and 100 (inclusive). */ export type NumberOfPercent = number export type NumberOfBytes = number /** * Same as `number`, but with semantic meaning that it's an Integer. */ export type Integer = number export type PositiveInteger = number export type NonNegativeInteger = number export type PositiveNumber = number export type NonNegativeNumber = number /** * Same as `number`, but with semantic meaning that it's a Float. */ export type Float = number export type PositiveFloat = number export type NonNegativeFloat = number /** * Convenience type alias, that allows to write this: * * data: NullableNumber[] * * instead of this: * * data: (number | null)[] */ export type NullableNumber = number | null export type NullablePositiveNumber = number | null export type NullableNonNegativeNumber = number | null export type NullableInteger = number | null export type NullablePositiveInteger = number | null export type NullableNotNegativeInteger = number | null export type NullableString = string | null export type NullableBoolean = boolean | null export type NullableBuffer = Buffer | null /** * Used as a compact representation of truthy value. * undefined ('' or other short falsy value) should be used as falsy value. */ export type ShortBoolean = '1' export type Base64String = string export type Base64UrlString = string export type JWTString = string export const JWT_REGEX = /^[\w-]+\.[\w-]+\.[\w-]+$/ export type SemVerString = string /** * HTML string that was safely escaped/sanitized. */ export type SafeHtml = Branded /** * Named type for JSON.parse / JSON.stringify second argument */ export type Reviver = (this: any, key: string, value: any) => any /** * Function to be passed to the `sort` method. * Returns -1 | 0 | 1 canonically, but any positive/negative number is supported. */ export type Comparator = (a: T, b: T) => number /** * Needed due to https://github.com/microsoft/TypeScript/issues/13778 * Only affects typings, no runtime effect. */ export const _stringMapValues = Object.values as (map: StringMap) => T[] /** * Needed due to https://github.com/microsoft/TypeScript/issues/13778 * Only affects typings, no runtime effect. */ export const _stringMapEntries = Object.entries as (map: StringMap) => [k: string, v: T][] /** * Alias of `Object.keys`, but returns keys typed as `keyof T`, not as just `string`. * This is how TypeScript should work, actually. * * Object.keys always returns strings, so numeric keys are stringified via `${K}`. * Symbol keys are excluded (Object.keys does not return symbols). */ export const _objectKeys = Object.keys as ( obj: Partial>, ) => (K extends string ? K : K extends number | bigint ? `${K}` : never)[] /** * Alias of `Object.entries`, but returns better-typed output. * * Difference with _stringMapEntries? * Use _stringMapEntries when the object is a StringMap - it'll correctly infer T being not undefined. * If the object is not a StringMap - use _objectEntries - it'll correctly infer object keys, which can be typed as Enum. * * So e.g you can use _objectEntries(obj).map([k, v] => {}) * and `k` will be `keyof obj` instead of generic `string`. */ export const _objectEntries = Object.entries as ( obj: Partial>, ) => [k: K extends string ? K : K extends number | bigint ? `${K}` : never, v: V][] export type NullishValue = null | undefined export type FalsyValue = false | '' | 0 | null | undefined /** * Utility function that helps to cast *existing variable* to needed type T. * * @example * try {} catch (err) { * // err is unknown here * _typeCast(err) * // now err is of type AppError * err.data = {} // can be done, because it was casted * } */ export function _typeCast(_v: any): asserts _v is T {} /** * Type-safe Object.assign that checks that part is indeed a Partial */ export const _objectAssign = Object.assign as ( target: T, part: Partial, ) => T /** * Defines a tuple of [err, data] * where only 1 of them exists. * Either error exists and data is null * Or error is null and data is defined. * This forces you to check `if (err)`, which lets * TypeScript infer the existence of `data`. * * Functions like pTry use that. */ export type ErrorDataTuple = [err: null, data: T] | [err: ERR, data: null] export type SortDirection = 'asc' | 'desc' export interface MutateOptions { /** * Defaults to false. */ mutate?: boolean } export interface SortOptions extends MutateOptions { /** * Defaults to 'asc'. */ dir?: SortDirection } export type Inclusiveness = '[]' | '[)' /** * @experimental */ export interface CommonClient extends AsyncDisposable { connected: boolean connect: () => Promise disconnect: () => Promise ping: () => Promise } export type Primitive = null | undefined | string | number | boolean | symbol | bigint export type Promisable = T | PromiseLike /** Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). */ export type Class = new (...args: any[]) => T /** Convert `object`s, `Map`s, `Set`s, and `Array`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 ``` // data.json { "foo": ["bar"] } // main.ts import {ReadonlyDeep} from 'type-fest'; import dataJson = require('./data.json'); const data: ReadonlyDeep = dataJson; export default data; // test.ts import data from './main'; data.foo.push('bar'); //=> error TS2339: Property 'push' does not exist on type 'readonly string[]' ``` */ /* oxlint-disable @typescript-eslint/no-restricted-types */ export type ReadonlyDeep = T extends Primitive | ((...args: any[]) => unknown) ? T : T extends ReadonlyMap ? ReadonlyMapDeep : T extends ReadonlySet ? ReadonlySetDeep : T extends object ? ReadonlyObjectDeep : unknown /** Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`. */ interface ReadonlyMapDeep extends ReadonlyMap< ReadonlyDeep, ReadonlyDeep > {} /** Same as `ReadonlyDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `ReadonlyDeep`. */ interface ReadonlySetDeep extends ReadonlySet> {} /** Same as `ReadonlyDeep`, but accepts only `object`s as inputs. Internal helper for `ReadonlyDeep`. */ type ReadonlyObjectDeep = { readonly [KeyType in keyof ObjectType]: ReadonlyDeep } /** Makes one property of T required instead of optional. @example ``` import { RequiredProp } from '@naturalcycles/js-lib/types' interface Example { a?: string b?: string }; type ExampleA = RequiredProp; //=> {a: string; b?: string}; ``` */ export type RequiredProp = Required> & T export type * from './typeFest.js'