Package Exports
- @avstantso/ts
- @avstantso/ts/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@avstantso/ts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@avstantso/ts
Advanced TypeScript type system utilities and helpers for creating powerful generic types, performing type-level computations, and building type-safe applications.
Features
- Type-level arithmetic - Increment, decrement, addition, subtraction, multiplication, division, and power operations on numeric literals
- Advanced array types - Create, manipulate, sort, filter, and transform array types with utilities like
Create,Sort,FilterUnique,Reverse,Join - String manipulation types - String length, case conversions (camelCase, PascalCase, snake_case, kebab-case), trimming, replacement, and pattern matching
- Union utilities - Convert unions to intersections, tuples, test for union types, and more
- Structure (object) utilities - Deep type manipulation, key/value extraction, flattening, reversing, splitting, and combining
- Comparison types - Type-level
<,<=,>,>=comparisons for both numbers and strings based on ASCII codes - ASCII character types - Complete ASCII character maps, character code lookups, and letter arrays
- Type resolution system - Resolve literal type names to their actual types with extensible literal registration
- Utility types - Alternative fields (
Alt), opaque types, type merging, key replacement, and conditional type selection - Comprehensive type system with zero runtime dependencies
Installation
npm install @avstantso/tsor
yarn add @avstantso/tsUsage
Global Access
Import the package to register the AVStantso.TS namespace globally:
import '@avstantso/ts';
// Use types from the global namespace
type Incremented = AVStantso.TS.Increment<5>; // 6
type Sorted = AVStantso.TS.Array.Sort<[3, 1, 2]>; // [1, 2, 3]
type CamelCase = AVStantso.TS.String.Case.Camel<'hello-world'>; // 'helloWorld'Direct Member Imports
Import the TS namespace directly for cleaner code:
import { TS } from '@avstantso/ts';
// Use imported TS namespace
type Incremented = TS.Increment<5>; // 6
type Sorted = TS.Array.Sort<[3, 1, 2]>; // [1, 2, 3]
type CamelCase = TS.String.Case.Camel<'hello-world'>; // 'helloWorld'
// Runtime utilities are also available
const field = TS.Array.ToKey2Key(['id', 'name', 'email'] as const);
console.log(field.id); // 'id'
const flattened = TS.flat({ a: 1, b: { c: 2 } }); // { a: 1, c: 2 }Exported Members:
TS- Complete TypeScript utilities namespace (same asAVStantso.TS)
API Reference
Type System Overview
The @avstantso/ts package provides a comprehensive suite of type-level utilities organized into the following namespaces:
- TS.Extends - Type extension checking
- TS.Increment / TS.Decrement - Numeric type arithmetic
- TS.Func - Function type utilities
- TS.Union - Union type manipulation
- TS.Array - Array type utilities
- TS.ASCII - ASCII character types and maps
- TS.Comparisons - Type-level comparisons
- TS.String - String type manipulation
- TS.Structure - Object structure utilities
- Object Constructor Extensions - Typed Object.keys/values/entries
- TS.Boolean - Boolean logic types
- TS.Numeric - Numeric literal utilities
- TS.Literal - Type literal definitions
- TS.Type - Type manipulation utilities
- TS.Resolve - Type literal resolution
- TS Utility Types - Miscellaneous utility types
TS.Extends
Type extension checking with support for undefined === undefined.
TS.Extends<T1, T2, IfTrue = true, IfFalse = false>
Check if T1 extends T2.
Type Parameters:
T1- The type to checkT2- The type to check againstIfTrue- Return value ifT1extendsT2(default:true)IfFalse- Return value ifT1does not extendT2(default:false)
Example:
import { TS } from '@avstantso/ts';
type IsString = TS.Extends<string, string>; // true
type IsNumber = TS.Extends<number, string>; // false
type WithCustom = TS.Extends<string, string, 'yes', 'no'>; // 'yes'TS.Increment / TS.Decrement
The cornerstone of many recursive type operations. Used for type-level iterations.
⛔ Inc/Dec Limitation
Current implementation has a limit of 999 iterations. Operations are defined on the Numeric.Domain.Positive range.
TS.Increment<N>
Increment numeric literal inside Numeric.Domain.Positive.
Type Parameters:
N- Numeric literal to increment (must be in range[0, 999])
Returns: N + 1 or number if out of range
Example:
import { TS } from '@avstantso/ts';
type Zero = TS.Increment<0>; // 1
type One = TS.Increment<1>; // 2
type Max = TS.Increment<255>; // 256
type Never = TS.Increment<never>; // numberTS.Decrement<N>
Decrement numeric literal inside Numeric.Domain.Positive.
Type Parameters:
N- Numeric literal to decrement (must be in range[0, 999])
Returns: N - 1 or number if out of range
Example:
import { TS } from '@avstantso/ts';
type Zero = TS.Decrement<0>; // -1
type One = TS.Decrement<1>; // 0
type Large = TS.Decrement<255>; // 254
type Never = TS.Decrement<never>; // numberTS.ArrN and TS.ArrM
TS.ArrN
readonly [any?, ... 996 more ...?, any?] - Array type constraint for Increment/Decrement-dependent types.
TS.ArrM<T = any, N extends number = 2>
Array of N items or more.
Type Parameters:
T- Element type (default:any)N- Minimum number of elements (default:2)
Example:
import { TS } from '@avstantso/ts';
type AtLeastTwo = TS.ArrM<string, 2>; // [string, string, ...string[]]
type AtLeastThree = TS.ArrM<number, 3>; // [number, number, number, ...number[]]TS.Func
Extends function types defined in the @avstantso/core package.
TS.Func.Nested<Depth, R, P>
Nested function generic type.
Type Parameters:
Depth- Nesting depthR- Return type of the innermost functionP- Parameter types (optional)
Example:
import { TS } from '@avstantso/ts';
type TripleNested = TS.Func.Nested<3, number>;
// Equivalent to: () => () => () => number
const fn: TripleNested = () => () => () => 42;TS.Union
Union type utilities based on microsoft/TypeScript#13298 and Shannon Jackson's implementation.
TS.Union.ToIntersection<U>
Convert a union to an intersection: X | Y | Z → X & Y & Z.
Example:
import { TS } from '@avstantso/ts';
type Union = { a: number } | { b: string };
type Intersection = TS.Union.ToIntersection<Union>; // { a: number } & { b: string }TS.Union.Pop<U>
Takes last item from union: X | Y | Z → Z.
Warning: May not always take the actual last item due to union ordering.
TS.Union.ToTuple<U>
Convert union to tuple: X | Y | Z → [X, Y, Z].
Warning: Order of items is not guaranteed.
Example:
import { TS } from '@avstantso/ts';
type Union = 'a' | 'b' | 'c';
type Tuple = TS.Union.ToTuple<Union>; // ['a', 'b', 'c'] (order may vary)TS.Union.IsUnion<T, IfTrue = true, IfFalse = false>
Test if type is a union.
Example:
import { TS } from '@avstantso/ts';
type MyUnion = 'a' | 'b' | 'c';
type NotUnion = string;
type Check1 = TS.Union.IsUnion<MyUnion>; // true
type Check2 = TS.Union.IsUnion<NotUnion>; // false
type Check3 = TS.Union.IsUnion<never>; // false
type Check4 = TS.Union.IsUnion<number | boolean>; // trueTS.Array
Comprehensive array type utilities for creation, manipulation, searching, and transformation.
Array Creation Types
TS.Array.Create<L, Item>
Creates array of Item with specified length L. ⛔Inc/Dec
Example:
import { TS } from '@avstantso/ts';
type FiveThrees = TS.Array.Create<5, 3>; // [3, 3, 3, 3, 3]TS.Array.Create.Optional<L, Item>
Creates optional array of Item with specified length L. ⛔Inc/Dec
Example:
import { TS } from '@avstantso/ts';
type FiveOptional = TS.Array.Create.Optional<5, 3>; // [3?, 3?, 3?, 3?, 3?]TS.Array.Numbers<L>
Creates numeric literals array from 0 to L-1. ⛔Inc/Dec
Example:
import { TS } from '@avstantso/ts';
type FirstThree = TS.Array.Numbers<3>; // [0, 1, 2]TS.Array.Letters<L>
Creates letters literals array with length L. ⛔Inc/Dec
Example:
import { TS } from '@avstantso/ts';
type ABC = TS.Array.Letters<3>; // ['A', 'B', 'C']Array Analysis Types
TS.Array.Length<TArr>
Get array type length.
Example:
import { TS } from '@avstantso/ts';
type Len = TS.Array.Length<[1, 5, 7]>; // 3TS.Array.Length.IfExeeded<TArr, N, IfTrue = true, IfFalse = false>
Test if array type length exceeds N.
Example:
import { TS } from '@avstantso/ts';
type Exceeded = TS.Array.Length.IfExeeded<[1, 5, 7], 2>; // true
type NotExceeded = TS.Array.Length.IfExeeded<[1, 5, 7], 3>; // falseArray Search Types
TS.Array.IndexOf<TArr, Item, I = 0>
Find index of type in array type.
Example:
import { TS } from '@avstantso/ts';
type Idx = TS.Array.IndexOf<[undefined, undefined, 'x'], 'x'>; // 2TS.Array.IfHasItem<TArr, Item, IfTrue = true, IfFalse = false>
Test if array type has item.
Example:
import { TS } from '@avstantso/ts';
type Has = TS.Array.IfHasItem<[1, undefined, 3, 4], 4>; // trueTS.Array.IfEach<TArr, Item, IfTrue = true, IfFalse = false>
Test if each item in array type extends Item.
Example:
import { TS } from '@avstantso/ts';
type AllUndefined = TS.Array.IfEach<[undefined, undefined, undefined], undefined>; // true
type NotAll = TS.Array.IfEach<[undefined, undefined, 3], undefined>; // falseTS.Array.CountOf<TArr, Item>
Calculate count of items that extend Item in array TArr.
Example:
import { TS } from '@avstantso/ts';
type Count1 = TS.Array.CountOf<[1, 2, 3], 3>; // 1
type Count3 = TS.Array.CountOf<[2, 2, 2], 2>; // 3Array Transformation Types
TS.Array.AddUnique<TArr, Item>
Create array type with addition if item does not exist.
Example:
import { TS } from '@avstantso/ts';
type Added = TS.Array.AddUnique<[2, 3], 1>; // [2, 3, 1]
type NotAdded = TS.Array.AddUnique<[1, 2, 3], 1>; // [1, 2, 3]TS.Array.MergeUnique<TArr1, TArr2>
Create merged array type from two arrays without duplicates from TArr2.
Example:
import { TS } from '@avstantso/ts';
type Merged = TS.Array.MergeUnique<[6, 1, 4], [1, 2, 3, 1, 4, 2, 5]>; // [6, 1, 4, 2, 3, 5]
type WithUndefined = TS.Array.MergeUnique<[6, 1, 4], [1, 2, undefined, 1, 4, 2, undefined]>;
// [6, 1, 4, 2, undefined]TS.Array.FilterUnique<TArr>
Create array type from array without duplicates.
Example:
import { TS } from '@avstantso/ts';
type Unique = TS.Array.FilterUnique<[1, 2, 3, 1, 4, 2, 5]>; // [1, 2, 3, 4, 5]
type WithUndefined = TS.Array.FilterUnique<[1, 2, 3, undefined, 1, 4, undefined, 5]>;
// [1, 2, 3, undefined, 4, 5]TS.Array.Sub<TArr, Start, End>
Create sub array type from Start to End (exclusive).
Example:
import { TS } from '@avstantso/ts';
type SubArray = TS.Array.Sub<[1, 2, 3, undefined, 5, 6], 2, 5>; // [3, undefined, 5]
type All = TS.Array.Sub<[1, 2, 3, 4, 5, 6], undefined, undefined>; // [1, 2, 3, 4, 5, 6]TS.Array.Remove<TArr, Start, End>
Create new array type without removed section.
Example:
import { TS } from '@avstantso/ts';
type Removed = TS.Array.Remove<[1, 2, 3, 4, 5, 6], 2, 5>; // [1, 2, 6]
type Empty = TS.Array.Remove<[1, 2, 3, 4, 5, 6], undefined, undefined>; // []TS.Array.Reverse<TArr>
Reverse array type.
Example:
import { TS } from '@avstantso/ts';
type Reversed = TS.Array.Reverse<[1, 2, 3]>; // [3, 2, 1]
type Mixed = TS.Array.Reverse<[1, undefined, 3, 'a']>; // ['a', 3, undefined, 1]TS.Array.Join<TArr>
Join array type to string.
Example:
import { TS } from '@avstantso/ts';
type Joined = TS.Array.Join<[1, 2, 3]>; // '123'
type ReadonlyJoined = TS.Array.Join<readonly ['a', 1, true, 123456789012345]>;
// 'a1true123456789012345'TS.Array.Cast<TArr, Item = any>
Cast all TArr items to Item type (items that don't match become never).
Example:
import { TS } from '@avstantso/ts';
type Same = TS.Array.Cast<[1, 2, 3]>; // [1, 2, 3]
type Numbers = TS.Array.Cast<[1, 2, 3], number>; // [1, 2, 3]
type Strings = TS.Array.Cast<[1, 2, 3], string>; // [never, never, never]
type Mixed = TS.Array.Cast<[1, undefined, 3], string>; // [never, undefined, never]Array Map/Record Types
TS.Array.ToKey<TArr>
Calculate key union from array of keys (equivalent to TArr[number]).
Example:
import { TS } from '@avstantso/ts';
type Keys = TS.Array.ToKey<['a', 1]>; // 'a' | 1
type ReadonlyKeys = TS.Array.ToKey<readonly ['a', 1]>; // 'a' | 1TS.Array.ToKey2Key<TArr>
Calculate key-to-key record from array of keys.
Example:
import { TS } from '@avstantso/ts';
type KeyMap = TS.Array.ToKey2Key<['a', 1]>; // { a: 'a', 1: 1 }TS.Array.ToRecord<TArr, T>
Calculate record of type T with keys from array.
Example:
import { TS } from '@avstantso/ts';
type StringRecord = TS.Array.ToRecord<['a'], string>; // { a: string }
type BoolRecord = TS.Array.ToRecord<['a', 1], boolean>; // { a: boolean, 1: boolean }TS.Array.KeyValueMapFrom<Keys, FirstValue = 0>
Create key-value map from list of keys and first value. Used in TS.ASCII.
Example:
import { TS } from '@avstantso/ts';
type Map1 = TS.Array.KeyValueMapFrom<['a', undefined, 1]>; // { a: 0; 1: 2 }
type Map2 = TS.Array.KeyValueMapFrom<['a', never, 1]>; // { a: 0; 1: 2 }TS.Array.ValueKeyMapFrom<Keys, FirstValue = 0>
Create value-key map from list of keys and first value.
Example:
import { TS } from '@avstantso/ts';
type Map = TS.Array.ValueKeyMapFrom<['a', undefined, 1]>; // { 0: 'a'; 1: undefined; 2: 1 }Array Min/Max/Sort Types
TS.Array.Min<TArr>
Find array minimal item.
Example:
import { TS } from '@avstantso/ts';
type MinNum = TS.Array.Min<[2, 1]>; // 1
type MinNumWithUndefined = TS.Array.Min<[2, undefined, 1]>; // 1
type MinStr = TS.Array.Min<['b', 'a']>; // 'a'
type MinStrWithUndefined = TS.Array.Min<['b', undefined, 'a']>; // 'a'TS.Array.Min.Index<TArr>
Find array minimal item index.
Example:
import { TS } from '@avstantso/ts';
type Idx1 = TS.Array.Min.Index<[2, 1]>; // 1
type Idx2 = TS.Array.Min.Index<[1, 2]>; // 0
type IdxStr = TS.Array.Min.Index<['b', undefined, 'a']>; // 2TS.Array.Max<TArr>
Find array maximal item.
Example:
import { TS } from '@avstantso/ts';
type MaxNum = TS.Array.Max<[2, 1]>; // 2
type MaxNumWithUndefined = TS.Array.Max<[2, undefined, 1]>; // 2
type MaxStr = TS.Array.Max<['b', 'a']>; // 'b'TS.Array.Max.Index<TArr>
Find array maximal item index.
Example:
import { TS } from '@avstantso/ts';
type Idx1 = TS.Array.Max.Index<[1, 2]>; // 1
type Idx2 = TS.Array.Max.Index<[1, undefined, 2]>; // 2TS.Array.Sort<TArr, Asc = true>
Sort array items. Allows sorting array of Sort.Pair<K> to sort any data by key. Based on TS.Comparisons.
Example:
import { TS } from '@avstantso/ts';
type Numbers = [1, 4, 5, 3, 2, 78, 1];
type Sorted = TS.Array.Sort<Numbers>; // [1, 1, 2, 3, 4, 5, 78]
type SortedDesc = TS.Array.Sort<Numbers, false>; // [78, 5, 4, 3, 2, 1, 1]
type Strings = ['abc', 'eb', '', '1', 'ab', ' '];
type SortedStr = TS.Array.Sort<Strings>; // ['', ' ', '1', 'ab', 'abc', 'eb']
type SortedStrDesc = TS.Array.Sort<Strings, false>; // ['eb', 'abc', 'ab', '1', ' ', '']
// Sort by key using pairs
type Pairs = [[1, 'one'], [3, 'three'], [2, 'two']];
type SortedPairs = TS.Array.Sort<Pairs>; // [[1, 'one'], [2, 'two'], [3, 'three']]TS.Array.Sort.Pair<K>
Pair key-data for sorting any data by key. First element is the sort key, second is the data.
TS.Array.Sort.Desc<TArr>
Sort array items descending (equivalent to Sort<TArr, false>).
Array Runtime Utilities
TS.Array.ToKey2Key<A>(arr: A)
Create key-to-key record from array for convenient field comparisons.
Parameters:
arr- Readonly array of keys
Returns: Object with keys mapping to themselves
Example:
import { TS } from '@avstantso/ts';
const Fields = ['id', 'name', 'version'] as const;
const Field = TS.Array.ToKey2Key(Fields);
// Type-safe field comparisons
if (Field.id === field) {
console.log('Is "id"');
}
if (Field.name === field) {
console.log('Is "name"');
}
if (Field.version === field) {
console.log('Is "version"');
}TS.ASCII
ASCII character types and utilities based on ascii-code.com. Used in TS.Comparisons for string comparison operations.
ASCII Types
TS.ASCII.Letters<IsUpper = true>
English letters array generic by case.
Example:
import { TS } from '@avstantso/ts';
type Upper = TS.ASCII.Letters<true>; // Letters.Upper
type Lower = TS.ASCII.Letters<false>; // Letters.LowerTS.ASCII.Letters.Upper
English uppercase letters array type: ['A', 'B', 'C', ..., 'Z'].
TS.ASCII.Letters.Lower
English lowercase letters array type: ['a', 'b', 'c', ..., 'z'].
TS.ASCII
Readonly array type of all ASCII characters (character codes 0-255).
TS.ASCII.Control
Readonly array type of ASCII control characters (character codes 0-31).
TS.ASCII.Printable
Readonly array type of ASCII printable characters (character codes 32-127).
TS.ASCII.Extended
Readonly array type of extended ASCII codes (character codes 128-255).
TS.ASCII.Map
ASCII character to code map for all characters.
TS.ASCII.Map.Control
ASCII character to code map for control characters (codes 0-31).
TS.ASCII.Map.Printable
ASCII character to code map for printable characters (codes 32-127).
TS.ASCII.Map.Extended
ASCII character to code map for extended ASCII codes (codes 128-255).
TS.ASCII.Code<S>
Get ASCII character code of string S. Returns never if S is not a single character.
Example:
import { TS } from '@avstantso/ts';
type CodeA = TS.ASCII.Code<'A'>; // 65
type CodeSpace = TS.ASCII.Code<' '>; // 32
type Invalid = TS.ASCII.Code<'AB'>; // neverTS.ASCII.Character
Union of all ASCII characters.
ASCII Runtime Utilities
TS.ASCII
Runtime array of all ASCII characters.
Example:
import { TS } from '@avstantso/ts';
console.log(TS.ASCII[65]); // 'A'
console.log(TS.ASCII.length); // 256TS.Comparisons
Type-level number and string comparisons.
String comparison is based on TS.ASCII character-to-number conversion. Number comparison splits numbers into digit arrays, compares lengths, then iterates through digits from most to least significant.
Comparison Types
TS.Comparisons.LT<A, B, IfTrue = true, IfFalse = false>
Test if A < B.
Example:
import { TS } from '@avstantso/ts';
type NumLess = TS.Comparisons.LT<1, 2>; // true
type NumNotLess = TS.Comparisons.LT<2, 1>; // false
type StrLess = TS.Comparisons.LT<'a', 'b'>; // trueTS.Comparisons.LTE<A, B, IfTrue = true, IfFalse = false>
Test if A <= B.
Example:
import { TS } from '@avstantso/ts';
type NumLessEq = TS.Comparisons.LTE<1, 1>; // true
type StrLessEq = TS.Comparisons.LTE<'a', 'a'>; // trueTS.Comparisons.GT<A, B, IfTrue = true, IfFalse = false>
Test if A > B.
Example:
import { TS } from '@avstantso/ts';
type NumGreater = TS.Comparisons.GT<2, 1>; // true
type StrGreater = TS.Comparisons.GT<'b', 'a'>; // trueTS.Comparisons.GTE<A, B, IfTrue = true, IfFalse = false>
Test if A >= B.
Example:
import { TS } from '@avstantso/ts';
type NumGreaterEq = TS.Comparisons.GTE<2, 2>; // true
type StrGreaterEq = TS.Comparisons.GTE<'b', 'b'>; // trueTS.String
String type manipulation utilities.
Basic String Types
TS.String.Possible
Types that can be converted to string literal using template literals: string | number | bigint | boolean.
Example:
import { TS } from '@avstantso/ts';
type Valid = `${TS.String.Possible}`; // string
type InvalidSymbol = `${symbol}`; // Error: Type 'symbol' is not assignableTS.String.Pattern
Regular expression pattern shortcuts.
export interface Pattern {
'\\s': ' \r\n\t\f\v' // Whitespace characters
}String Analysis Types
TS.String.Length<S>
Calculate string literal length.
Example:
import { TS } from '@avstantso/ts';
type Len0 = TS.String.Length<''>; // 0
type Len1 = TS.String.Length<'A'>; // 1
type Len2 = TS.String.Length<'AB'>; // 2TS.String.IsLengthBetween<S, Min, Max = Min, IfTrue = true, IfFalse = false>
Test if string literal length is in range [Min, Max].
Example:
import { TS } from '@avstantso/ts';
type Valid0 = TS.String.IsLengthBetween<'', 0>; // true
type Invalid0 = TS.String.IsLengthBetween<'', 1>; // false
type ValidRange = TS.String.IsLengthBetween<'A', 1, 2>; // trueTS.String.SplitToChars<S>
Split string literal into array of characters.
Example:
import { TS } from '@avstantso/ts';
type Empty = TS.String.SplitToChars<''>; // []
type Single = TS.String.SplitToChars<'A'>; // ['A']
type Multiple = TS.String.SplitToChars<'AB'>; // ['A', 'B']String Manipulation Types
TS.String.Repeat<S, N>
Repeat string S by N times. ⛔Inc/Dec
Example:
import { TS } from '@avstantso/ts';
type Empty = TS.String.Repeat<'AB', 0>; // ''
type Triple = TS.String.Repeat<'A1', 3>; // 'A1A1A1'TS.String.Includes<S, P, IfTrue = true, IfFalse = false>
Test if string S includes pattern P.
Example:
import { TS } from '@avstantso/ts';
type EmptyInEmpty = TS.String.Includes<'', ''>; // true
type EmptyInString = TS.String.Includes<'AB', ''>; // true
type CharInString = TS.String.Includes<'AB', 'A'>; // true
type FullMatch = TS.String.Includes<'AB', 'AB'>; // true
type Number = TS.String.Includes<'A8B', 8>; // true
type Boolean = TS.String.Includes<'AfalseB', false>; // true
type NotFound = TS.String.Includes<'AB', 'C'>; // falseTS.String.IndexOf<S, P>
Find index of pattern P in string S. Returns -1 if not found. Returns sorted array of pairs for union P.
Example:
import { TS } from '@avstantso/ts';
type Invalid1 = TS.String.IndexOf<'', ''>; // never
type Invalid2 = TS.String.IndexOf<'AB', ''>; // never
type FirstChar = TS.String.IndexOf<'AB', 'A'>; // 0
type SecondChar = TS.String.IndexOf<'AB', 'B'>; // 1
type Full = TS.String.IndexOf<'AB', 'AB'>; // 0
type NumIdx = TS.String.IndexOf<'A8B', 8>; // 1
type BoolIdx = TS.String.IndexOf<'AfalseB', false>; // 1
type NotFound = TS.String.IndexOf<'AB', 'C'>; // -1
// Union returns sorted pairs [index, match]
type Multiple = TS.String.IndexOf<'AfalseB', 'B' | false | 'l'>;
// [[1, false], [3, 'l'], [6, 'B']]TS.String.Replace<S, M, T, N = 9999>
Replace in string S all substrings matching M with T, up to N times. M can be a union.
Example:
import { TS } from '@avstantso/ts';
type RemoveChars = TS.String.Replace<TS.String.Replace<'a-b_c_d', '_'>, '-'>; // 'abcd'
type Limited = TS.String.Replace<'123456_246', '2' | '4' | '6', '#', 3>; // '1#3#5#_246'
type Multiple = TS.String.Replace<'abcde', 'a' | 'b' | 'c' | 'd' | 'e', 'x '>;
// 'x x x x x 'TS.String.Trim<S>
Remove whitespace characters from start and end of string S.
Example:
import { TS } from '@avstantso/ts';
type NoTrim = TS.String.Trim<'abcd'>; // 'abcd'
type Trimmed = TS.String.Trim<' \r\n\t\f\v \r\n\t\f\v123456 \r\n\t\f\v \r\n\t\f\v'>;
// '123456'TS.String.Trim.Start<S>
Remove whitespace characters from start of string S.
Example:
import { TS } from '@avstantso/ts';
type TrimStart = TS.String.Trim.Start<' \r\n\t\f\v123456 \r\n\t\f\v'>;
// '123456 \r\n\t\f\v'TS.String.Trim.End<S>
Remove whitespace characters from end of string S.
Example:
import { TS } from '@avstantso/ts';
type TrimEnd = TS.String.Trim.End<' \r\n\t\f\v123456 \r\n\t\f\v'>;
// ' \r\n\t\f\v123456'String Case Types
TS.String.Case<Type, S, R = Removes>
Convert string S to specified case format.
Case Types:
'c'- camelCase'p'- PascalCase's'- snake_case'S'- SNAKE_UPPER_CASE'k'- kebab-case
Example:
import { TS } from '@avstantso/ts';
type Phrase = 'Oh! Jingle bells, jingle bells Jingle all the way';
type Camel = TS.String.Case<'c', Phrase>; // 'ohJingleBellsJingleBellsJingleAllTheWay'
type Pascal = TS.String.Case<'p', Phrase>; // 'OhJingleBellsJingleBellsJingleAllTheWay'
type Snake = TS.String.Case<'s', Phrase>; // 'oh_jingle_bells_jingle_bells_jingle_all_the_way'
type SnakeUp = TS.String.Case<'S', Phrase>; // 'OH_JINGLE_BELLS_JINGLE_BELLS_JINGLE_ALL_THE_WAY'
type Kebab = TS.String.Case<'k', Phrase>; // 'oh-jingle-bells-jingle-bells-jingle-all-the-way'TS.String.Case.Settings.Removes
Characters to remove during case conversion: ' ' | '-' | '_' | ',' | '.' | '!'.
TS.String.Case.Settings.Removes.Map
Map of characters to remove (values ignored, only keys matter).
export interface AVStantso.TS.String.Case.Settings.Removes.Map {
' ': 0;
'-': 0;
'_': 0;
',': 0;
'.': 0;
'!': 0;
}You can extend this interface for custom character removal.
TS.String.Case.Camel<S, R = Removes>
Convert to camelCase.
TS.String.Case.Pascal<S, R = Removes>
Convert to PascalCase.
TS.String.Case.Snake<S, R = Removes>
Convert to snake_case.
TS.String.Case.Snake.Up<S, R = Removes>
Convert to SNAKE_UPPER_CASE.
TS.String.Case.Kebab<S, R = Removes>
Convert to kebab-case.
TS.Structure
Utilities for object types with fields (excludes special types like Array, Map, Set).
Structure Test Types
TS.Structure.IfStructure<T, IfTrue = true, IfFalse = false>
Test if T is a structure object (not a special object type).
Example:
import { TS } from '@avstantso/ts';
type Number = TS.Structure.IfStructure<number>; // false
type String = TS.Structure.IfStructure<string>; // false
type Object = TS.Structure.IfStructure<{}>; // true
type ObjectType = TS.Structure.IfStructure<object>; // true
type Array = TS.Structure.IfStructure<[]>; // false
type Date = TS.Structure.IfStructure<Date>; // false
type Buffer = TS.Structure.IfStructure<Buffer>; // false
type Map = TS.Structure.IfStructure<Map<unknown, unknown>>; // false
type Set = TS.Structure.IfStructure<Set<unknown>>; // false
type PlainFunc = TS.Structure.IfStructure<(x: number) => string>; // false
type FuncWithProps = TS.Structure.IfStructure<((x: number) => string) & { y: 15 }>; // trueTS.Structure<T>
Constraint that T is a structure object.
TS.Structure.Wildcard
Non-strict structure type (any object structure).
TS.Structure.MapOfNotRules
Used as rules source in IfStructure. If a type extends one of these values, it's not a structure.
export interface MapOfNotRules extends AtomicObjects {
Array: ReadonlyArray<unknown>;
Map: ReadonlyMap<unknown, unknown>;
Set: ReadonlySet<unknown>;
}TS.Structure.NotRules
Rules for IfStructure (union of MapOfNotRules values).
Structure Conversion Types
TS.Structure.ToKeysArray<O>
Transform structure O to keys array. Based on TS.Union.ToTuple.
Example:
import { TS } from '@avstantso/ts';
type Keys1 = TS.Structure.ToKeysArray<{ a: 1, b: true }>; // ['a', 'b']
type Keys2 = TS.Structure.ToKeysArray<{ a: 1, b: true, c: () => null }>; // ['a', 'b', 'c']
type Invalid = TS.Structure.ToKeysArray<[]>; // neverTS.Structure.ToValuesArray<O>
Transform structure O to values array. Based on TS.Union.ToTuple.
Example:
import { TS } from '@avstantso/ts';
type Values1 = TS.Structure.ToValuesArray<{ a: 1, b: true }>; // [1, true]
type Values2 = TS.Structure.ToValuesArray<{ a: 1, b: true, c: () => null }>;
// [1, true, () => null]
type Invalid = TS.Structure.ToValuesArray<[]>; // neverTS.Structure.ToEntriesArray<O>
Transform structure O to entries array (key-value pairs). Based on TS.Union.ToTuple.
Example:
import { TS } from '@avstantso/ts';
type Entries1 = TS.Structure.ToEntriesArray<{ a: 1, b: true }>;
// [['a', 1], ['b', true]]
type Entries2 = TS.Structure.ToEntriesArray<{ a: 1, b: true, c: () => null }>;
// [['a', 1], ['b', true], ['c', () => null]]
type Invalid = TS.Structure.ToEntriesArray<[]>; // neverStructure Manipulation Types
TS.Structure.Separate<T>
Separate structure object T into plain and structural fields: [<Plain>, <Structural>].
Example:
import { TS } from '@avstantso/ts';
type Sep1 = TS.Structure.Separate<{
a: number;
b: { c: string };
d: string;
e: number[];
}>;
// [{
// a: number;
// d: string;
// e: number[];
// }, {
// b: { c: string };
// }]
type Sep2 = TS.Structure.Separate<{
v: () => Buffer;
w: (() => string) & { n: string };
}>;
// [{
// v: () => Buffer;
// }, {
// w: (() => string) & { n: string };
// }]TS.Structure.Reverse<T, TProviderField = never>
Reverse structure object T to value-key map. Non-keyable values are ignored except objects with TProviderField.
Example:
import { TS } from '@avstantso/ts';
type Simple = TS.Structure.Reverse<{ x: 1; y: 'ABC'; z: { a: true } }>;
// { 1: 'x'; ABC: 'y' }
type WithProvider = TS.Structure.Reverse<{ x: 1; y: 'ABC'; z: { a: 15 } }, 'a'>;
// { 1: 'x'; ABC: 'y'; 15: 'z' }TS.Structure.Split<O>
Split structural object O into array of single-field objects. Based on TS.Union.ToTuple.
Example:
import { TS } from '@avstantso/ts';
type Obj = {
a: number;
b: string;
c: { x: bigint };
};
type Split = TS.Structure.Split<Obj>;
// [
// { a: number },
// { b: string },
// { c: { x: bigint } }
// ]TS.Structure.Combine<A>
Combine array A of structural object parts into single object.
Example:
import { TS } from '@avstantso/ts';
type Combined = TS.Structure.Combine<readonly [
{ a: number },
{ b: string },
{ c: { x: bigint } }
]>;
// {
// a: number;
// b: string;
// c: { x: bigint };
// }Structure Runtime Utilities
TS.Structure.is<T>(candidate, noSpecialClasses?): candidate is T
Check if candidate is a structure object and cast to T.
Parameters:
candidate- Value to testnoSpecialClasses- If true, returnsfalseforArray,Map,Set, etc.
Example:
import { TS } from '@avstantso/ts';
const obj = { a: 1, b: 2 };
if (TS.Structure.is(obj)) {
// obj is structure object
}
const arr = [1, 2, 3];
console.log(TS.Structure.is(arr)); // true (arrays are objects)
console.log(TS.Structure.is(arr, true)); // false (noSpecialClasses)TS.Structure.keyByValue<T>(structure, value, field?)
Find structure object key by value or subvalue with field.
Parameters:
structure- Object to search invalue- Value to findfield- Optional field name for nested value lookup
Example:
import { TS } from '@avstantso/ts';
const config = { debug: 1, info: 2, error: 3 };
const key = TS.Structure.keyByValue(config, 2); // 'info'
const nested = { a: { id: 1 }, b: { id: 2 } };
const nestedKey = TS.Structure.keyByValue(nested, 2, 'id'); // 'b'TS.Structure.reverse<T>(structure, field?)
Reverse structure object T to value-key map at runtime.
Parameters:
structure- Object to reversefield- Optional field for extracting values from nested objects
Example:
import { TS } from '@avstantso/ts';
const config = { debug: 1, info: 2, error: 3 };
const reversed = TS.Structure.reverse(config);
// { 1: 'debug', 2: 'info', 3: 'error' }Object Constructor Extensions
The package extends the Object constructor with typed versions of keys, values, and entries that preserve type information.
Object.keysEx<O>(o: O)
Returns typed array of enumerable string property names. Unlike Object.keys(), this preserves the exact key types.
Parameters:
o- Object to extract keys from
Returns: TS.Structure.ToKeysArray<O> - Typed array of keys
Example:
import '@avstantso/ts';
const obj = { id: 1, name: 'John', active: true } as const;
// Standard Object.keys - loses type information
const keys1 = Object.keys(obj); // string[]
// Object.keysEx - preserves exact key types
const keys2 = Object.keysEx(obj); // ['id', 'name', 'active']
// Type: ('id' | 'name' | 'active')[]
// Now you can use type-safe key access
keys2.forEach(key => {
console.log(obj[key]); // TypeScript knows key is valid
});Object.valuesEx<O>(o: O)
Returns typed array of enumerable property values. Unlike Object.values(), this preserves the exact value types.
Parameters:
o- Object to extract values from
Returns: TS.Structure.ToValuesArray<O> - Typed array of values
Example:
import '@avstantso/ts';
const obj = { id: 1, name: 'John', active: true } as const;
// Standard Object.values - loses type information
const values1 = Object.values(obj); // (string | number | boolean)[]
// Object.valuesEx - preserves exact value types
const values2 = Object.valuesEx(obj); // [1, 'John', true]
// Type: [1, 'John', true]
// Type information is preserved
const [id, name, active] = values2;
// id: 1, name: 'John', active: trueObject.entriesEx<O>(o: O)
Returns typed array of key-value pairs. Unlike Object.entries(), this preserves both key and value types.
Parameters:
o- Object to extract entries from
Returns: TS.Structure.ToEntriesArray<O> - Typed array of [key, value] pairs
Example:
import '@avstantso/ts';
const obj = { id: 1, name: 'John', active: true } as const;
// Standard Object.entries - loses type information
const entries1 = Object.entries(obj);
// [string, string | number | boolean][]
// Object.entriesEx - preserves exact key and value types
const entries2 = Object.entriesEx(obj);
// [['id', 1], ['name', 'John'], ['active', true]]
// Type: (['id', 1] | ['name', 'John'] | ['active', true])[]
// Type-safe iteration
entries2.forEach(([key, value]) => {
// TypeScript knows the exact type of key and value for each entry
console.log(`${key}: ${value}`);
});
// Type-safe destructuring
const [[idKey, idValue], [nameKey, nameValue], [activeKey, activeValue]] = entries2;
// idKey: 'id', idValue: 1
// nameKey: 'name', nameValue: 'John'
// activeKey: 'active', activeValue: trueUse Cases:
These typed extensions are particularly useful when:
- Working with configuration objects where type safety matters
- Iterating over object properties with type guarantees
- Building type-safe mappers and transformers
- Ensuring key-value correspondence in operations
Example - Type-Safe Object Mapper:
import '@avstantso/ts';
function mapObjectValues<T extends object, R>(
obj: T,
mapper: <K extends keyof T>(key: K, value: T[K]) => R
): Record<keyof T, R> {
return Object.entriesEx(obj).reduce((acc, [key, value]) => {
acc[key] = mapper(key, value);
return acc;
}, {} as Record<keyof T, R>);
}
const user = { id: 1, name: 'John', age: 30 } as const;
// Type-safe mapping with preserved keys
const stringified = mapObjectValues(user, (key, value) => {
// key and value have exact types based on the object
return `${key}: ${value}`;
});
// Result: { id: 'id: 1', name: 'name: John', age: 'age: 30' }TS.Boolean
Boolean type utilities and logical operations.
TS.If<Condition, IfTrue = true, IfFalse = false>
Conditional type selection.
Example:
import { TS } from '@avstantso/ts';
type Yes = TS.If<true, 'yes', 'no'>; // 'yes'
type No = TS.If<false, 'yes', 'no'>; // 'no'TS.If.And<Conditions, IfTrue = true, IfFalse = false>
Logical AND on array of conditions.
Example:
import { TS } from '@avstantso/ts';
type AllTrue = TS.If.And<[true, true, true]>; // true
type OneFalse = TS.If.And<[true, false, true]>; // falseTS.If.Or<Conditions, IfTrue = true, IfFalse = false>
Logical OR on array of conditions.
Example:
import { TS } from '@avstantso/ts';
type HasTrue = TS.If.Or<[false, true, false]>; // true
type AllFalse = TS.If.Or<[false, false, false]>; // falseTS.If.Xor<Conditions, IfTrue = true, IfFalse = false>
Logical XOR on array of conditions (true if exactly one condition is true).
Example:
import { TS } from '@avstantso/ts';
type OnlyOne = TS.If.Xor<[false, true, false]>; // true
type Multiple = TS.If.Xor<[true, true, false]>; // false
type None = TS.If.Xor<[false, false, false]>; // falseTS.Numeric
Numeric literal type utilities for type-level arithmetic and analysis.
Domain-Independent Types
TS.Numeric.IsPositive<N, IfTrue = true, IfFalse = false>
Test if number N is positive.
Example:
import { TS } from '@avstantso/ts';
type Positive = TS.Numeric.IsPositive<1>; // true
type Zero = TS.Numeric.IsPositive<0>; // false
type Negative = TS.Numeric.IsPositive<-1>; // false
type Never = TS.Numeric.IsPositive<never>; // never
type Undef = TS.Numeric.IsPositive<undefined>; // falseTS.Numeric.IsNegative<N, IfTrue = true, IfFalse = false>
Test if number N is negative.
Example:
import { TS } from '@avstantso/ts';
type Negative = TS.Numeric.IsNegative<-1>; // true
type Zero = TS.Numeric.IsNegative<0>; // false
type Positive = TS.Numeric.IsNegative<1>; // falseTS.Numeric.Positive.ToNegative<N>
Get negative of absolute value of numeric literal.
Example:
import { TS } from '@avstantso/ts';
type Zero = TS.Numeric.Positive.ToNegative<0>; // 0
type Neg1 = TS.Numeric.Positive.ToNegative<1>; // -1
type Neg255 = TS.Numeric.Positive.ToNegative<255>; // -255
type AlreadyNeg = TS.Numeric.Positive.ToNegative<-1>; // -1TS.Numeric.Negative.ToPositive<N>
Get absolute value of negative numeric literal.
Example:
import { TS } from '@avstantso/ts';
type Zero = TS.Numeric.Negative.ToPositive<0>; // 0
type Pos1 = TS.Numeric.Negative.ToPositive<-1>; // 1
type Pos255 = TS.Numeric.Negative.ToPositive<-255>; // 255
type AlreadyPos = TS.Numeric.Negative.ToPositive<1>; // 1TS.Numeric.Sign<N = any>
Get sign of number N: -1 | 0 | 1. Without parameter, returns the sign union type.
Example:
import { TS } from '@avstantso/ts';
type Pos = TS.Numeric.Sign<42>; // 1
type Neg = TS.Numeric.Sign<-42>; // -1
type Zero = TS.Numeric.Sign<0>; // 0
type SignUnion = TS.Numeric.Sign; // -1 | 0 | 1TS.Numeric.Digits
Union of digit characters: keyof Digits.Map.
TS.Numeric.Digits.Map
Record of digit character to digit number: { '0': 0, '1': 1, ..., '9': 9 }.
TS.Numeric.Digits.IsOdd
Record of digit character to boolean indicating if odd: { '0': false, '1': true, ... }.
TS.Numeric.Digits.Hex
Union of hexadecimal digit characters: keyof Digits.Hex.Map.
Includes decimal digits (0-9) and hexadecimal letters (A-F).
Type Definition:
type Hex = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'TS.Numeric.Digits.Hex.Map
Record of hexadecimal digit character to itself, extending Digits.Map:
type Map = {
'0': 0;
'1': 1;
'2': 2;
'3': 3;
'4': 4;
'5': 5;
'6': 6;
'7': 7;
'8': 8;
'9': 9;
'A': 'A';
'B': 'B';
'C': 'C';
'D': 'D';
'E': 'E';
'F': 'F';
}Example:
import { TS } from '@avstantso/ts';
// Use in type constraints
type HexDigit = TS.Numeric.Digits.Hex;
// '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
// Validate hexadecimal strings
type IsHexChar<C extends string> = C extends HexDigit ? true : false;
type Valid1 = IsHexChar<'5'>; // true
type Valid2 = IsHexChar<'F'>; // true
type Invalid = IsHexChar<'G'>; // false
// Build hexadecimal string types
type HexByte = `${HexDigit}${HexDigit}`;
// '00' | '01' | ... | 'FF'
// ⚠ Watch out for TypeScript limits!
type ColorHex = `#${HexByte}${HexByte}${HexByte}`;
// '#000000' | '#000001' | ... | '#FFFFFF'TS.Numeric.IsOdd<N, IfTrue = true, IfFalse = false>
Test if number is odd.
Example:
import { TS } from '@avstantso/ts';
type Odd = TS.Numeric.IsOdd<11>; // true
type Even = TS.Numeric.IsOdd<32>; // falseTS.Numeric.IsEven<N, IfTrue = true, IfFalse = false>
Test if number is even.
Example:
import { TS } from '@avstantso/ts';
type Even = TS.Numeric.IsEven<32>; // true
type Odd = TS.Numeric.IsEven<11>; // falseTS.Numeric.IsNumber<S, IfTrue = true, IfFalse = false>
Test if string S represents a number.
Example:
import { TS } from '@avstantso/ts';
type ValidPos = TS.Numeric.IsNumber<'1000'>; // true
type ValidNeg = TS.Numeric.IsNumber<'-1'>; // true
type Invalid = TS.Numeric.IsNumber<'abc'>; // false
type DoubleNeg = TS.Numeric.IsNumber<'--1'>; // falseTS.Numeric.Parse<S>
Parse string S to extract number from it.
Example:
import { TS } from '@avstantso/ts';
type Zero = TS.Numeric.Parse<'0'>; // 0
type Pos = TS.Numeric.Parse<'255'>; // 255
type Neg = TS.Numeric.Parse<'-255'>; // -255
type Invalid = TS.Numeric.Parse<'abc'>; // never
type Never = TS.Numeric.Parse<never>; // never
type Undef = TS.Numeric.Parse<undefined>; // undefinedNumeric Domain Types
Internal types for numeric operations. These define the range of numeric literals that can be manipulated.
TS.Numeric.Domain.Positive
Array of positive numbers: [1, 2, ..., 4999, ...number[]].
TS.Numeric.Domain.Negative
Array of negative numbers: [-1, -2, ..., -4999, ...number[]].
TS.Numeric.Domain.Increment<N>
Increment numeric literal within the full domain (including negative numbers).
Example:
import { TS } from '@avstantso/ts';
type Inc10 = TS.Numeric.Domain.Increment<10>; // 11
type Inc0 = TS.Numeric.Domain.Increment<0>; // 1
type IncNeg = TS.Numeric.Domain.Increment<-1>; // 0
type IncNeg10 = TS.Numeric.Domain.Increment<-10>; // -9Note: This differs from TS.Increment which only works on 0 and positive numbers.
TS.Numeric.Domain.Decrement<N>
Decrement numeric literal within the full domain.
Example:
import { TS } from '@avstantso/ts';
type Dec10 = TS.Numeric.Domain.Decrement<10>; // 9
type Dec0 = TS.Numeric.Domain.Decrement<0>; // -1
type DecNeg = TS.Numeric.Domain.Decrement<-1>; // -2Numeric Math Types
Type-level arithmetic operations. Developed as an exploration of TypeScript's type system capabilities.
TS.Numeric.Abs<N>
Absolute value of numeric literal (alias for Negative.ToPositive<N>).
TS.Numeric.Invert<N>
Invert sign of numeric literal (positive ⇔ negative).
Example:
import { TS } from '@avstantso/ts';
type Zero = TS.Numeric.Invert<0>; // 0
type ToNeg = TS.Numeric.Invert<1>; // -1
type ToPos = TS.Numeric.Invert<-255>; // 255TS.Numeric.Summ<X, Y>
Calculate X + Y. Uses an optimized algorithm to avoid the 999 iteration limit.
Example:
import { TS } from '@avstantso/ts';
type Simple = TS.Numeric.Summ<8, 3>; // 11
type WithZero = TS.Numeric.Summ<0, 3>; // 3
type Negative = TS.Numeric.Summ<-8, 3>; // -5
type Large = TS.Numeric.Summ<20000, 997>; // 20997TS.Numeric.Diff<X, Y>
Calculate X - Y. Uses an optimized algorithm to avoid the 999 iteration limit.
Example:
import { TS } from '@avstantso/ts';
type Simple = TS.Numeric.Diff<8, 3>; // 5
type WithZero = TS.Numeric.Diff<0, 3>; // -3
type Negative = TS.Numeric.Diff<-8, 3>; // -11
type Large = TS.Numeric.Diff<20000, 997>; // 19003TS.Numeric.Multiply<X, Y>
Calculate X * Y.
Limitation: One of X or Y must be in range [-1000, 1000]. Beyond this range, you may encounter "Type instantiation is excessively deep" errors.
Example:
import { TS } from '@avstantso/ts';
type Simple = TS.Numeric.Multiply<8, 3>; // 24
type WithZero = TS.Numeric.Multiply<0, 3>; // 0
type Negative = TS.Numeric.Multiply<-8, 3>; // -24
type Large = TS.Numeric.Multiply<900000, -1000>; // -900000000TS.Numeric.Div<X, Y>
Calculate X / Y. Returns quotient if evenly divisible, otherwise [quotient, remainder]. Returns never for division by zero.
Limitation: One of X or Y must be in range [-1000, 1000].
Example:
import { TS } from '@avstantso/ts';
type DivByZero = TS.Numeric.Div<8, 0>; // never
type Zero = TS.Numeric.Div<0, 3>; // 0
type NotInt = TS.Numeric.Div<1, 3>; // null
type Simple1 = TS.Numeric.Div<8, 2>; // 4
type Simple2 = TS.Numeric.Div<8, 3>; // [2, 2] (quotient 2, remainder 2)
type Equal = TS.Numeric.Div<-68899, -68899>; // 1
type NegResult = TS.Numeric.Div<-34, 7>; // [-4, -6]
type MaxRange = TS.Numeric.Div<999999, 1000>; // [999, 999]TS.Numeric.Power<X, E>
Calculate X ^ E. If E is negative, returns never.
Limitation: Result must be within Numeric.Domain.Power range.
Example:
import { TS } from '@avstantso/ts';
type Pow1 = TS.Numeric.Power<3, 6>; // 729
type Pow2 = TS.Numeric.Power<3, 7>; // 2187
type NegBase1 = TS.Numeric.Power<-2, 1>; // -2
type NegBase2 = TS.Numeric.Power<-2, 2>; // 4TS.Literal
Core type definitions by their name literals. Provides a system for working with type names as strings.
Literal Types
TS.Literal
Union of literals for available value types.
TS.Literal.Map
Map of type name literals to actual types.
export interface AVStantso.TS.Literal.Map extends AtomicObjects {
string: string;
number: number;
bigint: bigint;
boolean: boolean;
symbol: symbol;
undefined: undefined;
object: object;
function: Function;
}You can extend this interface to add custom type literals.
TS.Literal.NumberLike
Map for number-like type names (key is significant, value ignored).
export interface AVStantso.TS.Literal.NumberLike {
number: 0;
bigint: 0;
Date: 0;
}TS.Literal.IsNumberLike<L, IfTrue = true, IfFalse = false>
Test if literal L represents a number-like type.
Example:
import { TS } from '@avstantso/ts';
type IsNum = TS.Literal.IsNumberLike<'number'>; // true
type IsObj = TS.Literal.IsNumberLike<'object'>; // falseTS.Literal.StringLike
Map for string-like type names (key is significant, value ignored).
export interface AVStantso.TS.Literal.StringLike {
string: 0;
Buffer: 0;
}TS.Literal.IsStringLike<L, IfTrue = true, IfFalse = false>
Test if literal L represents a string-like type.
Example:
import { TS } from '@avstantso/ts';
type IsStr = TS.Literal.IsStringLike<'string'>; // true
type IsObj = TS.Literal.IsStringLike<'object'>; // falseTS.Literal.List
Array of literals for available value types. Based on TS.Union.ToTuple<Literal>.
TS.Literal.Key2KeyRec
Literals key-to-key record for convenient comparisons.
Literal Runtime Utilities
TS.Literal
Runtime object with properties from Literal.Key2KeyRec and utility methods.
TS.Literal.List
Runtime array of literal strings.
Example:
import { TS } from '@avstantso/ts';
console.log(TS.Literal.List); // ['string', 'number', 'bigint', ...]TS.Literal.Empty(type)
Get empty value for a literal type. Has getter properties for each registered literal.
Example:
import { TS } from '@avstantso/ts';
const emptyStr = TS.Literal.Empty('string'); // ''
const emptyNum = TS.Literal.Empty('number'); // 0
const emptyObj = TS.Literal.Empty('object'); // {}TS.Literal.IsValue(type, value)
Test if value is of the specified literal type. Has function binding properties for each registered literal.
Example:
import { TS } from '@avstantso/ts';
console.log(TS.Literal.IsValue('string', 'hello')); // true
console.log(TS.Literal.IsValue('number', 'hello')); // false
// Using bound functions
console.log(TS.Literal.IsValue.string('hello')); // trueTS.Literal._Register(literal, empty?)
Register a custom type literal for extension.
Example:
import { TS } from '@avstantso/ts';
type XYZ = { x: string; y: number; z: boolean };
// Extend the namespace
namespace AVStantso.TS.Literal {
export interface Map {
xyz: XYZ;
}
}
// Register the literal
avstantso.TS.Literal._Register('xyz');
// Now you can use it
type Resolved = AVStantso.TS.Resolve<'xyz'>; // XYZ
console.log(avstantso.TS.Literal.List.includes('xyz')); // trueTS.Type
Type manipulation and definition utilities.
Type Types
TS.Type
Union of all available value types: string | number | bigint | boolean | symbol | object | Function | Date | Buffer.
TS.Type.Not<T>
Exclude specified type T from available types.
TS.Type.Not.Function
Available types excluding Function: Exclude<Type, Function>.
TS.Type.Not.Object
Available types excluding object: Exclude<Type, object>.
TS.Type.Not.String
Available types excluding string: Exclude<Type, string>.
TS.Type.Def
Type definition structure supporting Literal.
TS.Type.KeyDef
Keyed type definition structure.
TS.Type.KLD
Type definition array with key and optional default: [<key>, <type literal>, <default value>?].
TS.Type.Union<T>
Type union of T with Literal.
Example:
import { TS } from '@avstantso/ts';
type Never = TS.Type.Union<never>; // never
type Undef = TS.Type.Union<undefined>; // unknown
// Literals NOT supported as strings:
type LiteralStr = TS.Type.Union<string | 'bigint'>; // string
type WithLiteral = TS.Type.Union<number, 'string' | 'bigint'>; // number | 'string' | 'bigint'
type FromDef = TS.Type.Union<{ T: Function; L: 'boolean' }>; // 'boolean' | Function
type WithObject = TS.Type.Union<object>; // object | LiteralType Runtime Utilities
TS.Type.KeyDef(key, type)
Create keyed type definition structure at runtime.
Example:
import { TS } from '@avstantso/ts';
const keyDef = TS.Type.KeyDef('id', 'string');
// { K: 'id', L: 'string' }TS.Type.KLD(key, type, def?)
Create type definition array [<key>, <type literal>, <default value>?].
Example:
import { TS } from '@avstantso/ts';
const kld = TS.Type.KLD('id', 'string', '');
// ['id', 'string', '']TS.Resolve
Type literal resolution utilities for converting literal type names to actual types.
TS.Resolve<T>
Resolve Literal in type union T to their actual types.
Example:
import { TS } from '@avstantso/ts';
type Never = TS.Resolve<never>; // never
type Undef = TS.Resolve<undefined>; // unknown
// Literal strings NOT supported as type literals:
type StrWithLiteral = TS.Resolve<string | 'function'>; // string
type LiteralUnion = TS.Resolve<'bigint' | 'string'>; // string | bigint
type Direct = TS.Resolve<bigint>; // bigint
type Mixed = TS.Resolve<'bigint' | 'string' | boolean>; // string | bigint | boolean
type FromDef = TS.Resolve<{ T: Function; L: 'boolean' }>; // boolean | Function
type EmptyObj = TS.Resolve<{}>; // {}
type DefWithBase = TS.Resolve<{ T: string; L: 'string' | 'boolean' }>; // string | boolean
type DefMixed = TS.Resolve<{ T: string; L: 'function' }>; // string | Function
type OnlyLiteral = TS.Resolve<{ L: 'function' }>; // Function
type OnlyType = TS.Resolve<{ T: Function }>; // FunctionTS Utility Types
Miscellaneous utility types for advanced type manipulation.
TS.Alt<T>
Create object with alternative fields (only one field at a time, not all simultaneously).
If T is a structure object, each field becomes an alternative. If T is an array, each item becomes an alternative.
Example:
import { TS } from '@avstantso/ts';
type Obj = { a: number; b: string; c: { x: bigint } };
type AltObj = TS.Alt<Obj>;
// {
// a: number;
// b?: never;
// c?: never;
// } | {
// a?: never;
// b: string;
// c?: never;
// } | {
// a?: never;
// b?: never;
// c: { x: bigint };
// }
type Arr = [{ a: number; b: string }, { c: { x: bigint }; d: unknown }];
type AltArr = TS.Alt<Arr>;
// {
// a: number;
// b: string;
// c?: never;
// d?: never;
// } | {
// a?: never;
// b?: never;
// c: { x: bigint };
// d: unknown;
// }TS.Flat<T, Depth = 1>
Flatten object structure to specified depth.
Example:
import { TS } from '@avstantso/ts';
type Nested = {
v: () => Buffer;
w: (() => string) & { n: string };
x: { a: string; b: number };
y: { c: { d: boolean } };
z: bigint;
};
type Flat1 = TS.Flat<Nested>;
// {
// v: () => Buffer;
// z: bigint;
// n: string;
// a: string;
// b: number;
// c: { d: boolean };
// w: () => string;
// }
type Flat2 = TS.Flat<Nested, 2>;
// {
// v: () => Buffer;
// z: bigint;
// n: string;
// a: string;
// b: number;
// d: boolean;
// w: () => string;
// }TS.IfDef<TBase, TExtended, TElse = TBase>
Select TExtended if defined, otherwise TBase or TElse.
TS.IfDefKey<TKey, TBase, TExtended, TElse = TBase[TKey]>
Select TExtended[TKey] if defined, otherwise TBase[TKey] or TElse.
Example:
import { TS } from '@avstantso/ts';
type A = {
x?: number;
y?: number;
};
type B = {
x?: 1 | 2 | 3;
};
type XType = TS.IfDefKey<'x', A, B>; // 1 | 2 | 3
type YType = TS.IfDefKey<'y', A, B>; // numberTS.Opaque<TypeMeta, T>
Create opaque type that prevents direct assignment (nominal typing).
Example:
import { TS } from '@avstantso/ts';
type ID = TS.Opaque<'ID', string>;
// @ts-expect-error Type 'string' is not assignable to type 'ID'
const id1: ID = 'abc';
const id2: ID = 'def' as ID; // OK
const s: string = id1 + id2; // OK - can use as stringTS.Options<TTypeMap, TDefaults>
Options type for declarations with type mapping and defaults.
Override Types
TS.Override<TBase, TExtended, TOptional = false>
Override TBase properties with TExtended properties (only where TExtended[K] is not undefined).
Example:
import { TS } from '@avstantso/ts';
type A = {
x?: number;
y?: number;
z?: number;
};
type B = {
x?: 1 | 2 | 3;
y?: 12;
};
type Result = TS.Override<A, B>;
// { x?: 1 | 2 | 3; y?: 12; z?: number }TS.IfIsOverrided<TBase, TCurrent, IfTrue = true, IfFalse = false>
Test if TBase was overridden by TCurrent.
Example:
import { TS } from '@avstantso/ts';
type Overridden = TS.IfIsOverrided<number, 1 | 2 | 3>; // true
type NotOverridden = TS.IfIsOverrided<number, number>; // false
type UnknownBase = TS.IfIsOverrided<unknown, unknown>; // false
type UnknownOverridden = TS.IfIsOverrided<unknown, {}>; // trueTS.IfIsOverridedKey<TKey, TBase, TCurrent, IfTrue = true, IfFalse = false>
Test if TBase[Key] was overridden by TCurrent[Key].
Example:
import { TS } from '@avstantso/ts';
type Overridden = TS.IfIsOverridedKey<
'a',
{ a: number; b: string },
{ a: 1 | 2 | 3; b: string }
>; // true
type NotOverridden = TS.IfIsOverridedKey<
'a',
{ a: number; b: string },
{ a: number; b: string }
>; // falseTS.IfNotOverrided<TBase, TCurrent, TExtended>
Select TExtended if TBase and TCurrent are equal.
Example:
import { TS } from '@avstantso/ts';
type Overridden = TS.IfNotOverrided<number, 1 | 2 | 3, 2>; // 1 | 2 | 3
type NotOverridden = TS.IfNotOverrided<number, number, 4>; // 4TS.IfNotOverridedKey<TKey, TBase, TCurrent, TExtended>
Select TExtended[TKey] if TBase[TKey] and TCurrent[TKey] are equal.
TS.OverrideIfNot<TBase, TCurrent, TExtended, TOptional = false>
Override TCurrent properties with TExtended properties only where TCurrent[K] equals TBase[K].
Example:
import { TS } from '@avstantso/ts';
type A = {
a?: string;
b?: string;
x?: number;
y?: number;
z?: number;
};
type B = {
x?: 1 | 2 | 3;
y?: 12;
};
type C = {
b: 'b' | 'bb';
x?: 4;
z?: 72;
};
type Result = TS.OverrideIfNot<A, B, C>;
// {
// a?: string; // from A (not in B & C)
// b?: 'b' | 'bb'; // from C (not in B)
// x?: 1 | 2 | 3; // from B (overridden in B)
// y?: 12; // from B
// z?: 72; // from C (not in B)
// }TS.ReplaceKey<TKey, TBase, TReplacement, TOptional = false>
Replace key TKey in object or function TBase with TReplacement.
Example:
import { TS } from '@avstantso/ts';
type Required = TS.ReplaceKey<'a', { a: string; b: number }, []>;
// { a: []; b: number }
type Optional = TS.ReplaceKey<'a', { a: string; b: number }, [], true>;
// { a?: []; b: number }TS.ReplaceKeyOpt<TKey, TBase, TReplacement>
Replace key TKey optionally (equivalent to ReplaceKey<TKey, TBase, TReplacement, true>).
TS.RequiredKeys<T>
Get union of required keys from type T.
Example:
import { TS } from '@avstantso/ts';
type Keys = TS.RequiredKeys<{ a: 1; b?: 2 }>; // 'a'TS.OptionalKeys<T>
Get union of optional keys from type T.
Example:
import { TS } from '@avstantso/ts';
type Keys = TS.OptionalKeys<{ a: 1; b?: 2 }>; // 'b'TS.Merge<Base, Extended>
Merge types. Combines fields for objects, creates union for other types.
Example:
import { TS } from '@avstantso/ts';
type UnionTypes = TS.Merge<number, string>; // number | string
type MergeObjects = TS.Merge<{ a?: number; b?: string }, { a: string }>;
// { a: string; b?: string }TS.Merge.Fields<Base, Extended, BaseKey, ExtendedKey = BaseKey>
Merge specific fields of object types.
Example:
import { TS } from '@avstantso/ts';
type FieldA = TS.Merge.Fields<{ a?: number; b?: string }, { a: string }, 'a'>;
// number | string
type FieldB = TS.Merge.Fields<{ a?: number; b?: string }, { a: string }, 'b', 'a'>;
// stringUtility Runtime Functions
TS.isKey<K extends AVStantso.TS.Key>(candidate: unknown): candidate is K
Check if candidate has object key type (string, number, or symbol).
Example:
import { TS } from '@avstantso/ts';
const key: unknown = 'myKey';
if (TS.isKey(key)) {
// key is string | number | symbol
const obj = { [key]: 'value' };
}TS.flat(structure, depth = 1)
Flatten structure object to specified depth.
Warning: Creates wrappers for functions with extended properties. The this context will be lost.
Example:
import { TS } from '@avstantso/ts';
const data = {
a: 15,
b: {
c: {
s: 'my string'
}
},
d: () => 4
};
const flat1 = TS.flat(data);
// {
// a: 15,
// c: { s: 'my string' },
// d: [Function]
// }
const flat2 = TS.flat(data, 2);
// {
// a: 15,
// s: 'my string',
// d: [Function]
// }Requirements
- Node.js 12.0 or higher
- TypeScript 4.0 or higher (for TypeScript projects)
Dependencies
@avstantso/core- Core utilities and type definitions@avstantso/std-ext- Standard library extensions
License
MIT - See LICENSE file for details
Repository
GitLab - avstantso-js/cross-platform-utils
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests to the repository.