rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
218 lines (205 loc) • 5.9 kB
TypeScript
import type ElemFn from "./Elem";
import type IsFixedLengthFn from "./IsFixedLength";
import type IsReadonlyFn from "./IsReadonly";
import type IsTupleFn from "./IsTuple";
import type IsWritableFn from "./IsWritable";
import type MixFn from "./Mix";
import type MutateFn from "./Mutate";
import type OfReadonlyFn from "./OfReadonly";
import type OfWritableFn from "./OfWritable";
import type { PartialApply } from "../HKT";
import type { Lazied, Lazied$Get } from "../helpers";
/**
* Alias for `readonly T[]` to represent an `Array` or `ReadonlyArray`.
*/
export type Ary<T = unknown> = readonly T[];
/**
* {@link Lazied} version of {@link Ary}.
*/
export interface AryL<L extends Lazied> extends Ary<Lazied$Get<L>> {}
/**
* Alias for `readonly T[]`.
*/
export type ReadonlyAry<T> = readonly T[];
/**
* {@link Lazied} version of {@link ReadonlyAry}.
*/
export interface ReadonlyAryL<L extends Lazied> extends ReadonlyAry<Lazied$Get<L>> {}
/**
* Alias for `T[]`.
*/
export type WritableAry<T> = T[];
/**
* {@link Lazied} version of {@link WritableAry}.
*/
export interface WritableAryL<L extends Lazied> extends WritableAry<Lazied$Get<L>> {}
/***********
* Methods *
***********/
/**
* Methods for `Array` and `ReadonlyArray`.
*/
export namespace Ary {
/**
* [Fn] Get the element type of an {@link Ary} (i.e., `Array` or `ReadonlyArray`).
*
* Sig: `<T>(a: Ary<T>) => T`
*
* @example
* ```typescript
* type R1 = $<Ary.Elem, readonly string[]>;
* // ^?: string
* type R2 = $<Ary.Elem, (number | boolean)[]>;
* // ^?: number | boolean
* type R3 = $<Ary.Elem, []>;
* // ^?: never
* type R4 = $<Ary.Elem, [1, 2, 3]>;
* // ^?: 1 | 2 | 3
* ```
*/
export type Elem = ElemFn;
/**
* [Fn] Check if an {@link Ary} (i.e., `Array` or `ReadonlyArray`) is a fixed length
* one (i.e., the `length` property is a number literal).
*
* Sig: `(a: Ary) => boolean`
*
* @example
* ```typescript
* type R1 = $<Ary.IsFixedLength, string[]>;
* // ^?: false
* type R2 = $<Ary.IsFixedLength, readonly number[]>;
* // ^?: false
* type R3 = $<Ary.IsFixedLength, ["foo", "bar"]>;
* // ^?: true
* type R4 = $<Ary.IsFixedLength, readonly [42, 1337, ...string[]]>;
* // ^?: false
* ```
*/
export type IsFixedLength = IsFixedLengthFn;
/**
* [Fn] Check if an {@link Ary} (i.e., `Array` or `ReadonlyArray`) is a tuple.
*
* Sig: `(a: Ary) => boolean`
*
* @example
* ```typescript
* type R1 = $<Ary.IsTuple, string[]>;
* // ^?: false
* type R2 = $<Ary.IsTuple, readonly number[]>;
* // ^?: false
* type R3 = $<Ary.IsTuple, ["foo", "bar"]>;
* // ^?: true
* type R4 = $<Ary.IsTuple, readonly [42, 1337, ...string[]]>;
* // ^?: true
* type R6 = $<Ary.IsTuple, readonly [...string[]]>;
* // ^?: false, because `readonly [...string[]]` is actually equal to `readonly string[]`, and
* // the same is true for something like `[...(number | string)[]]`, which is equal
* // to `(number | string)[]`, etc.
* type R7 = $<Ary.IsTuple, []>;
* // ^?: true
* ```
*/
export type IsTuple = IsTupleFn;
/**
* [Fn] Check if an {@link Ary} (i.e., `Array` or `ReadonlyArray`) is readonly.
*
* Sig: `(a: Ary) => boolean`
*
* @example
* ```typescript
* type R1 = $<Ary.IsReadonly, string[]>;
* // ^?: false
* type R2 = $<Ary.IsReadonly, readonly number[]>;
* // ^?: true
* type R3 = $<Ary.IsReadonly, ["foo", "bar"]>;
* // ^?: false
* type R4 = $<Ary.IsReadonly, readonly [42, 1337, ...string[]]>;
* // ^?: true
* ```
*/
export type IsReadonly = IsReadonlyFn;
/**
* [Fn] Check if an {@link Ary} (i.e., `Array` or `ReadonlyArray`) is writable (i.e.,
* not readonly).
*
* Sig: `(a: Ary) => boolean`
*
* @example
* ```typescript
* type R1 = $<Ary.IsWritable, string[]>;
* // ^?: true
* type R2 = $<Ary.IsWritable, readonly number[]>;
* // ^?: false
* type R3 = $<Ary.IsWritable, ["foo", "bar"]>;
* // ^?: true
* type R4 = $<Ary.IsWritable, readonly [42, 1337, ...string[]]>;
* // ^?: false
* ```
*/
export type IsWritable = IsWritableFn;
/**
* [Fn] Mix a type with the element type of an {@link Ary} (i.e., `Array` or
* `ReadonlyArray`).
*
* Sig: `<T, U>[y: U](a: Ary<T>) => Ary<T | U>`
*
* @example
* ```typescript
* type R1 = $<Ary.Mix<number>, string[]>;
* // ^?: (string | number)[]
* type R2 = $<Ary.Mix<"foo">, readonly number[]>;
* // ^?: readonly (number | "foo")[]
* ```
*/
export type Mix<U> = PartialApply<MixFn, [U]>;
/**
* [Fn] Mutate the element type of an {@link Ary} (i.e., `Array` or `ReadonlyArray`).
*
* Sig: `<T, U>[y: U](a: Ary<T>) => Ary<U>`
*
* @example
* ```typescript
* type R1 = $<Ary.Mutate<number>, string[]>;
* // ^?: number[]
* type R2 = $<Ary.Mutate<"foo">, readonly number[]>;
* // ^?: readonly "foo"[]
* ```
*/
export type Mutate<U> = PartialApply<MutateFn, [U]>;
}
/******************
* Static members *
******************/
/**
* [Fn] Build a readonly array from a type.
*
* Sig: `<T>(x: T) => ReadonlyArray<T>`
*
* @example
* ```typescript
* type R1 = $<Ary$$OfReadonly, number>;
* // ^?: readonly number[]
* type R2 = $<Ary$$OfReadonly, 42 | string>;
* // ^?: readonly (42 | string)[]
* ```
*/
export type Ary$$OfReadonly = OfReadonlyFn;
/**
* [Fn] Build a writable array from a type.
*
* Sig: `<T>(x: T) => Array<T>`
*
* @example
* ```typescript
* type R1 = $<Ary$$OfWritable, number>;
* // ^?: number[]
* type R2 = $<Ary$$OfWritable, 42 | string>;
* // ^?: (42 | string)[]
* ```
*/
export type Ary$$OfWritable = OfWritableFn;
/****************
* Type classes *
****************/
export type { Ary$$Show } from "./Show";