@js-bits/typedef-utils
Advanced tools
Comparing version 0.0.10 to 1.0.0
@@ -5,4 +5,97 @@ # Module: math | ||
### Namespaces | ||
### Type Aliases | ||
- [MathUtils](math.MathUtils.md) | ||
- [Add](math.md#add) | ||
- [Multiply](math.md#multiply) | ||
- [Parse](math.md#parse) | ||
## Type Aliases | ||
### Add | ||
**Add**<`A`, `B`\>: `_Add_`<`A`, `B`\> | ||
Addition of two positive integer values represented by either a number or a string format | ||
**`Requires`** | ||
TypeScript 4.8+ | ||
**`Remarks`** | ||
The operation doesn't have any noticeable limitations | ||
**`Example`** | ||
```ts | ||
const smallValue: MathUtils.Add<3, 4> = 7; | ||
const bigValue: MathUtils.Add<9999999, 9999999> = 19999998; | ||
const stringArgs: MathUtils.Add<'1234567890', '987654321'> = 2222222211; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `A` | extends `string` \| `number` | any positive integer number | | ||
| `B` | extends `string` \| `number` | any positive integer number | | ||
___ | ||
### Multiply | ||
**Multiply**<`A`, `B`\>: `_Multiply_`<`A`, `B`\> | ||
Multiplies two positive integer values represented by either a number or a string format | ||
**`Requires`** | ||
TypeScript 4.8+ | ||
**`Remarks`** | ||
The first argument can be 999 max because of a [hardcoded limit in TypeScript compiler](https://github.com/microsoft/TypeScript/pull/45711) | ||
**`Example`** | ||
```ts | ||
const numberArgs: MathUtils.Multiply<78, 63> = 4914; | ||
const stringArgs: MathUtils.Multiply<'999', '999'> = 998001; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `A` | extends `string` \| `number` | any positive integer number from 0 to 999 | | ||
| `B` | extends `string` \| `number` | any positive integer number | | ||
___ | ||
### Parse | ||
**Parse**<`T`\>: `T` extends `number` ? `T` : `T` extends \`${infer N extends number}\` ? `N` : `never` | ||
Returns number by the given string representation | ||
**`Requires`** | ||
TypeScript 4.8+ | ||
**`Remarks`** | ||
[Related TypeScript issue](https://github.com/microsoft/TypeScript/pull/48094) | ||
**`Example`** | ||
```ts | ||
const intValue: MathUtils.Parse<'123'> = 123; | ||
const floatValue: MathUtils.Parse<'-56.78'> = -56.78; | ||
const stringArg: MathUtils.Parse<123> = 123; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `T` | extends `string` \| `number` | any number | |
@@ -5,4 +5,117 @@ # Module: string | ||
### Namespaces | ||
### Type Aliases | ||
- [StringUtils](string.StringUtils.md) | ||
- [Split](string.md#split) | ||
- [Trim](string.md#trim) | ||
- [TrimLeft](string.md#trimleft) | ||
- [TrimRight](string.md#trimright) | ||
- [Unique](string.md#unique) | ||
## Type Aliases | ||
### Split | ||
**Split**<`Str`, `Separator`, `NoEmpty`\>: `_Split_`<`Str`, `Separator`, `NoEmpty`\> | ||
Returns a tuple of substrings by splitting the string pattern by the given separator. | ||
Additionally you can filter out empty string from the resulting list by specifying the third argument as `true` | ||
**`Example`** | ||
```ts | ||
const arr: StringUtils.Split<'a b c', ' '> = ['a', 'b', 'c']; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `Str` | extends `string` | any string | | ||
| `Separator` | extends `string` | any string character | | ||
| `NoEmpty` | extends `boolean` = ``false`` | optional flag | | ||
___ | ||
### Trim | ||
**Trim**<`Str`, `Spacer`\>: [`TrimLeft`](string.md#trimleft)<[`TrimRight`](string.md#trimright)<`Str`, `Spacer`\>, `Spacer`\> | ||
Removes leading and trailing white spaces (or the specified characters) from the given string | ||
**`Example`** | ||
```ts | ||
const str1: StringUtils.Trim<' abc '> = 'abc'; | ||
const str2: StringUtils.Trim<'*******abc*******', '*'> = 'abc'; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `Str` | extends `string` | any string | | ||
| `Spacer` | extends `string` = ``" "`` | optional string character | | ||
___ | ||
### TrimLeft | ||
**TrimLeft**<`Str`, `Spacer`\>: `Str` extends \`${Spacer}${infer Part}\` ? [`TrimLeft`](string.md#trimleft)<`Part`, `Spacer`\> : `Str` | ||
Removes leading white spaces (or the specified characters) from the given string | ||
**`Example`** | ||
```ts | ||
const str1: StringUtils.TrimLeft<' abc'> = 'abc'; | ||
const str2: StringUtils.TrimLeft<'*******abc', '*'> = 'abc'; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `Str` | extends `string` | any string | | ||
| `Spacer` | extends `string` = ``" "`` | any string | | ||
___ | ||
### TrimRight | ||
**TrimRight**<`Str`, `Spacer`\>: `Str` extends \`${infer Part}${Spacer}\` ? [`TrimRight`](string.md#trimright)<`Part`, `Spacer`\> : `Str` | ||
Removes trailing white spaces (or the specified characters) from the given string | ||
**`Example`** | ||
```ts | ||
const str1: StringUtils.TrimRight<'abc '> = 'abc'; | ||
const str2: StringUtils.TrimRight<'abc*******', '*'> = 'abc'; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `Str` | extends `string` | any string | | ||
| `Spacer` | extends `string` = ``" "`` | optional string character | | ||
___ | ||
### Unique | ||
**Unique**<`A`\>: `NotEmptyString`<`A`[`number`]\> | ||
Transforms a tuple of strings into a union of string values | ||
**`Example`** | ||
```ts | ||
type StringUnion = StringUtils.Unique<['a', 'a', 'b', 'c', 'c']>; // "a" | "b" | "c" | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `A` | extends `string`[] | any string tuple | |
@@ -5,4 +5,75 @@ # Module: tuple | ||
### Namespaces | ||
### Type Aliases | ||
- [TupleUtils](tuple.TupleUtils.md) | ||
- [Append](tuple.md#append) | ||
- [Length](tuple.md#length) | ||
- [Longest](tuple.md#longest) | ||
## Type Aliases | ||
### Append | ||
**Append**<`A`, `Item`, `NoEmpty`\>: `NoEmpty` extends ``true`` ? `Item` extends ``""`` ? `A` : [...A, `Item`] : [...A, `Item`] | ||
Appends new item to the given tuple. | ||
Optionally you can ignore empty strings by specifying the third argument as `true` | ||
**`Example`** | ||
```ts | ||
const arr: TupleUtils.Append<[1, 2, 3, 4], 5> = [1, 2, 3, 4, 5]; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `A` | extends `unknown`[] | any tuple | | ||
| `Item` | `Item` | any value | | ||
| `NoEmpty` | extends `boolean` = ``false`` | optional flag | | ||
___ | ||
### Length | ||
**Length**<`A`\>: `A` extends { `length`: infer L } ? `L` : `never` | ||
Returns length of the given tuple | ||
**`Example`** | ||
```ts | ||
const length: TupleUtils.Length<[1, 2, 3, 4, 5]> = 5; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `A` | extends `unknown`[] | any tuple | | ||
___ | ||
### Longest | ||
**Longest**<`A`, `B`\>: `B`[[`Length`](tuple.md#length)<`A`\>] extends `undefined` ? `A` : `B` | ||
Compares two tuples by their length and returns either the longest one of them | ||
or the first one if they are the same length | ||
**`Remarks`** | ||
All items of both tuples must be defined in order for the operation to work properly | ||
**`Example`** | ||
```ts | ||
const longest: TupleUtils.Longest<[1], [1, 2, 3]> = [1, 2, 3]; | ||
``` | ||
#### Type parameters | ||
| Name | Type | Description | | ||
| :------ | :------ | :------ | | ||
| `A` | extends `unknown`[] | any tuple without undefined items | | ||
| `B` | extends `unknown`[] | any tuple without undefined items | |
{ | ||
"name": "@js-bits/typedef-utils", | ||
"version": "0.0.10", | ||
"version": "1.0.0", | ||
"description": "Utility types for TypeScript", | ||
@@ -20,7 +20,18 @@ "keywords": [ | ||
"type": "module", | ||
"types": "dist/index.d.ts", | ||
"exports": { | ||
"./math": "./types/math.ts", | ||
"./string": "./types/string.ts", | ||
"./tuple": "./types/tuple.ts" | ||
}, | ||
"typesVersions": { | ||
"*": { | ||
"*": [ | ||
"./dist/*" | ||
] | ||
} | ||
}, | ||
"scripts": { | ||
"lint": "tsc --noEmit && eslint '**/*.{js,jsx,ts,tsx}'", | ||
"test": "yarn lint", | ||
"build": "rimraf ./dist && tsc types/*.ts --emitDeclarationOnly --declaration --outFile dist/index.d.ts", | ||
"build": "rimraf ./dist && tsc types/*.ts --emitDeclarationOnly --declaration --outDir dist", | ||
"docs": "rimraf ./docs && typedoc types/*.ts --plugin typedoc-plugin-markdown --disableSources --readme none --hideMembersSymbol --hideBreadcrumbs", | ||
@@ -27,0 +38,0 @@ "prepare": "husky install" |
/* eslint-disable import/extensions, @typescript-eslint/no-unused-vars, camelcase */ | ||
import { Add, AddString, Multiply, Normalize, Parse, SplitDigits, SumDigits, ToNumber } from '../types/math'; | ||
const test_ParseInt: MathUtils.Parse<'123'> = 123; | ||
const test_ParseInt2: MathUtils.Parse<123> = 123; | ||
const test_ParseFloat: MathUtils.Parse<'56.78'> = 56.78; | ||
const test_ParseNegative: MathUtils.Parse<'-56.78'> = -56.78; | ||
const test_ParseInt: Parse<'123'> = 123; | ||
const test_ParseInt2: Parse<123> = 123; | ||
const test_ParseFloat: Parse<'56.78'> = 56.78; | ||
const test_ParseNegative: Parse<'-56.78'> = -56.78; | ||
const test_SplitDigits1: MathUtils.SplitDigits<'1234'> = ['4', '3', '2', '1', '0']; | ||
const test_SplitDigits1: SplitDigits<'1234'> = ['4', '3', '2', '1', '0']; | ||
const test_SumDigits1: MathUtils.SumDigits<'9', '9'> = 18; | ||
const test_SumDigits2: MathUtils.SumDigits<'1', '2'> = 3; | ||
const test_SumDigits1: SumDigits<'9', '9'> = 18; | ||
const test_SumDigits2: SumDigits<'1', '2'> = 3; | ||
const test_AddString1: MathUtils.AddString<'3', '85'> = [8, 8, 0]; | ||
const test_AddString2: MathUtils.AddString<'99', '1'> = [10, 9, 0]; | ||
const test_AddString1: AddString<'3', '85'> = [8, 8, 0]; | ||
const test_AddString2: AddString<'99', '1'> = [10, 9, 0]; | ||
const test_ToNumber1: MathUtils.ToNumber<[1, 2, 3, 0]> = '0321'; | ||
const test_ToNumber2: MathUtils.ToNumber<[10, 12, 0]> = '130'; | ||
const test_ToNumber1: ToNumber<[1, 2, 3, 0]> = '0321'; | ||
const test_ToNumber2: ToNumber<[10, 12, 0]> = '130'; | ||
const test_Normalize1: MathUtils.Normalize<'0000000123'> = '123'; | ||
const test_Normalize2: MathUtils.Normalize<'123000000'> = '123000000'; | ||
const test_Normalize1: Normalize<'0000000123'> = '123'; | ||
const test_Normalize2: Normalize<'123000000'> = '123000000'; | ||
const test_Add0: MathUtils.Add<3, 4> = 7; | ||
const test_Add1: MathUtils.Add<1999, 1> = 2000; | ||
const test_Add2: MathUtils.Add<9, 1> = 10; | ||
const test_Add3: MathUtils.Add<99, 1> = 100; | ||
const test_Add4: MathUtils.Add<999, 1> = 1000; | ||
const test_Add5: MathUtils.Add<999, 999> = 1998; | ||
const test_Add6: MathUtils.Add<9, 99999999999> = 100000000008; | ||
const test_Add7: MathUtils.Add<99999999999, 9> = 100000000008; | ||
const test_Add8: MathUtils.Add<9999999, 9999999> = 19999998; | ||
const test_Add9: MathUtils.Add<'1234567890', '987654321'> = 2222222211; | ||
const test_Add0: Add<3, 4> = 7; | ||
const test_Add1: Add<1999, 1> = 2000; | ||
const test_Add2: Add<9, 1> = 10; | ||
const test_Add3: Add<99, 1> = 100; | ||
const test_Add4: Add<999, 1> = 1000; | ||
const test_Add5: Add<999, 999> = 1998; | ||
const test_Add6: Add<9, 99999999999> = 100000000008; | ||
const test_Add7: Add<99999999999, 9> = 100000000008; | ||
const test_Add8: Add<9999999, 9999999> = 19999998; | ||
const test_Add9: Add<'1234567890', '987654321'> = 2222222211; | ||
// A is limited to 999, B is "limitless" | ||
const test_Multiply1: MathUtils.Multiply<999, 99999999> = 99899999001; | ||
const test_Multiply2: MathUtils.Multiply<199, 3> = 597; | ||
const test_Multiply3: MathUtils.Multiply<78, 63> = 4914; | ||
const test_Multiply4: MathUtils.Multiply<'999', '999'> = 998001; | ||
const test_Multiply1: Multiply<999, 99999999> = 99899999001; | ||
const test_Multiply2: Multiply<199, 3> = 597; | ||
const test_Multiply3: Multiply<78, 63> = 4914; | ||
const test_Multiply4: Multiply<'999', '999'> = 998001; |
/* eslint-disable @typescript-eslint/no-unused-vars, camelcase, import/extensions */ | ||
import { Split, Trim, Unique } from '../types/string'; | ||
import { MULTI_LINE_LIST, SINGLE_LINE_LIST, SINGLE_LINE_LONG_STRING } from './string.data'; | ||
let test_trimEmpty: StringUtils.Trim<' '> = ''; | ||
let test_trimEmpty: Trim<' '> = ''; | ||
// @ts-expect-error Type '"abc"' is not assignable to type '""' | ||
test_trimEmpty = 'abc'; | ||
const test_trimNone: StringUtils.Trim<'option_l0'> = 'option_l0'; | ||
const test_trimNone: Trim<'option_l0'> = 'option_l0'; | ||
const test_trimLeftSingle: StringUtils.Trim<' option_l1'> = 'option_l1'; | ||
let test_trimLeftMultiple: StringUtils.Trim<' option_l2'> = 'option_l2'; | ||
const test_trimLeftSingle: Trim<' option_l1'> = 'option_l1'; | ||
let test_trimLeftMultiple: Trim<' option_l2'> = 'option_l2'; | ||
// @ts-expect-error Type '"option_l3"' is not assignable to type '"option_l2"' | ||
test_trimLeftMultiple = 'option_l3'; | ||
const test_trimRightSingle: StringUtils.Trim<'option_r1 '> = 'option_r1'; | ||
let test_trimRightMutliple: StringUtils.Trim<'option_r2 '> = 'option_r2'; | ||
const test_trimRightSingle: Trim<'option_r1 '> = 'option_r1'; | ||
let test_trimRightMutliple: Trim<'option_r2 '> = 'option_r2'; | ||
// @ts-expect-error Type '"option_r3"' is not assignable to type '"option_r2"' | ||
test_trimRightMutliple = 'option_r3'; | ||
const test_trimCenterSingle: StringUtils.Trim<' option_c1 '> = 'option_c1'; | ||
const test_trimCenterMultiple: StringUtils.Trim<' option_c2 '> = 'option_c2'; | ||
const test_trimCenterDashes: StringUtils.Trim<'-------option_c3---------', '-'> = 'option_c3'; | ||
const test_trimCenterSingle: Trim<' option_c1 '> = 'option_c1'; | ||
const test_trimCenterMultiple: Trim<' option_c2 '> = 'option_c2'; | ||
const test_trimCenterDashes: Trim<'-------option_c3---------', '-'> = 'option_c3'; | ||
let test_trimSingleLineLimits: StringUtils.Trim<SINGLE_LINE_LONG_STRING> = 'string'; | ||
let test_trimSingleLineLimits: Trim<SINGLE_LINE_LONG_STRING> = 'string'; | ||
// @ts-expect-error Type '"abc"' is not assignable to type '"string"' | ||
test_trimSingleLineLimits = 'abc'; | ||
const test_splitNoneSpace: StringUtils.Split<'a b c', '\n'> = ['a b c']; | ||
const test_splitNoneNewLine: StringUtils.Split<'a\nb\nc', ' '> = ['a\nb\nc']; | ||
const test_splitNoneSpace: Split<'a b c', '\n'> = ['a b c']; | ||
const test_splitNoneNewLine: Split<'a\nb\nc', ' '> = ['a\nb\nc']; | ||
const test_splitNewLine1: StringUtils.Split<'a\nb\nc', '\n'> = ['a', 'b', 'c']; | ||
const test_splitNewLine2: StringUtils.Split<'a\nb\nc\n', '\n'> = ['a', 'b', 'c', '']; | ||
const test_splitNewLine3: StringUtils.Split< | ||
const test_splitNewLine1: Split<'a\nb\nc', '\n'> = ['a', 'b', 'c']; | ||
const test_splitNewLine2: Split<'a\nb\nc\n', '\n'> = ['a', 'b', 'c', '']; | ||
const test_splitNewLine3: Split< | ||
` | ||
@@ -42,31 +43,31 @@ a | ||
const test_splitSpace1: StringUtils.Split<'a b c', ' '> = ['a', 'b', 'c']; | ||
const test_splitSpace2: StringUtils.Split<' a b c ', ' '> = ['', 'a', 'b', 'c']; | ||
const test_splitSpace1: Split<'a b c', ' '> = ['a', 'b', 'c']; | ||
const test_splitSpace2: Split<' a b c ', ' '> = ['', 'a', 'b', 'c']; | ||
const test_splitNoEmpty1: StringUtils.Split<'\na\nb\nc\n', '\n', true> = ['a', 'b', 'c']; | ||
const test_splitNoEmpty2: StringUtils.Split<' a b c ', ' ', true> = ['a', 'b', 'c']; | ||
const test_splitNoEmpty1: Split<'\na\nb\nc\n', '\n', true> = ['a', 'b', 'c']; | ||
const test_splitNoEmpty2: Split<' a b c ', ' ', true> = ['a', 'b', 'c']; | ||
const test_SplitSingleLineLimits21: StringUtils.Split<SINGLE_LINE_LIST, ' '>[10] = 'OPTION011'; | ||
const test_SplitSingleLineLimits21: Split<SINGLE_LINE_LIST, ' '>[10] = 'OPTION011'; | ||
// @ts-expect-error Type '"OPTION010"' is not assignable to type '"OPTION011"' | ||
const test_SplitSingleLineLimits22: StringUtils.Split<SINGLE_LINE_LIST, ' '>[10] = 'OPTION010'; | ||
const test_SplitSingleLineLimits3: StringUtils.Split<SINGLE_LINE_LIST, ' '>[99] = 'OPTION100'; | ||
const test_SplitSingleLineLimits4: StringUtils.Split<SINGLE_LINE_LIST, ' '>[998] = 'OPTION999'; | ||
const test_SplitSingleLineLimits22: Split<SINGLE_LINE_LIST, ' '>[10] = 'OPTION010'; | ||
const test_SplitSingleLineLimits3: Split<SINGLE_LINE_LIST, ' '>[99] = 'OPTION100'; | ||
const test_SplitSingleLineLimits4: Split<SINGLE_LINE_LIST, ' '>[998] = 'OPTION999'; | ||
const test_SplitMultiLineLimits1: StringUtils.Split<MULTI_LINE_LIST, '\n'>[0] = ''; | ||
const test_SplitMultiLineLimits21: StringUtils.Split<MULTI_LINE_LIST, '\n'>[10] = 'OPTION010'; | ||
const test_SplitMultiLineLimits1: Split<MULTI_LINE_LIST, '\n'>[0] = ''; | ||
const test_SplitMultiLineLimits21: Split<MULTI_LINE_LIST, '\n'>[10] = 'OPTION010'; | ||
// @ts-expect-error Type '"OPTION011"' is not assignable to type '"OPTION010"' | ||
const test_SplitMultiLineLimits22: StringUtils.Split<MULTI_LINE_LIST, '\n'>[10] = 'OPTION011'; | ||
const test_SplitMultiLineLimits3: StringUtils.Split<MULTI_LINE_LIST, '\n'>[100] = 'OPTION100'; | ||
const test_SplitMultiLineLimits4: StringUtils.Split<MULTI_LINE_LIST, '\n'>[997] = 'OPTION997'; | ||
const test_SplitMultiLineLimits5: StringUtils.Split<MULTI_LINE_LIST, '\n'>[998] = ''; | ||
const test_SplitMultiLineLimits22: Split<MULTI_LINE_LIST, '\n'>[10] = 'OPTION011'; | ||
const test_SplitMultiLineLimits3: Split<MULTI_LINE_LIST, '\n'>[100] = 'OPTION100'; | ||
const test_SplitMultiLineLimits4: Split<MULTI_LINE_LIST, '\n'>[997] = 'OPTION997'; | ||
const test_SplitMultiLineLimits5: Split<MULTI_LINE_LIST, '\n'>[998] = ''; | ||
const test_SplitUnionLimits1: StringUtils.Unique<StringUtils.Split<MULTI_LINE_LIST, '\n'>> = 'OPTION010'; | ||
const test_SplitUnionLimits2: StringUtils.Unique<StringUtils.Split<MULTI_LINE_LIST, '\n'>> = 'OPTION997'; | ||
const test_SplitUnionLimits1: Unique<Split<MULTI_LINE_LIST, '\n'>> = 'OPTION010'; | ||
const test_SplitUnionLimits2: Unique<Split<MULTI_LINE_LIST, '\n'>> = 'OPTION997'; | ||
// @ts-expect-error Type '"OPTION999"' is not assignable to type 'Unique<["", "OPTION001", "OPTION002", ... | ||
const test_SplitUnionLimits3: StringUtils.Unique<StringUtils.Split<MULTI_LINE_LIST>> = 'OPTION999'; | ||
const test_SplitUnionLimits3: Unique<Split<MULTI_LINE_LIST>> = 'OPTION999'; | ||
// @ts-expect-error Type '""' is not assignable to type 'Unique<["", "OPTION001", "OPTION002", ... | ||
const test_SplitUnionLimits4: StringUtils.Unique<StringUtils.Split<MULTI_LINE_LIST>> = ''; | ||
const test_SplitUnionLimits4: Unique<Split<MULTI_LINE_LIST>> = ''; | ||
// @ts-expect-error Type '""' is not assignable to type 'Unique<["OPTION001", "OPTION002", | ||
const test_SplitUnionLimits5: StringUtils.Unique<StringUtils.Split<SINGLE_LINE_LIST, ' '>> = ''; | ||
const test_SplitUnionLimits5: Unique<Split<SINGLE_LINE_LIST, ' '>> = ''; | ||
// @ts-expect-error Type '"OPTION000"' is not assignable to type 'Unique<["OPTION001", "OPTION002", ... | ||
const test_SplitUnionLimits6: StringUtils.Unique<StringUtils.Split<SINGLE_LINE_LIST, ' '>> = 'OPTION000'; | ||
const test_SplitUnionLimits6: Unique<Split<SINGLE_LINE_LIST, ' '>> = 'OPTION000'; |
/* eslint-disable @typescript-eslint/no-unused-vars, import/extensions, camelcase */ | ||
const test_Length1: TupleUtils.Length<[1, 2, 3, 4, 5]> = 5; | ||
const test_Length2: TupleUtils.Length<[]> = 0; | ||
const test_Length3: TupleUtils.Length<['a', 'b', 'c']> = 3; | ||
import { Append, Length, Longest } from '../types/tuple'; | ||
const lest_Longest1: TupleUtils.Longest<[1, 1, 1], [2, 2, 2]> = [1, 1, 1]; | ||
const lest_Longest2: TupleUtils.Longest<[1, 1], [2, 2, 2]> = [2, 2, 2]; | ||
const lest_Longest3: TupleUtils.Longest<[1, 1, 1, 1, 1], [2]> = [1, 1, 1, 1, 1]; | ||
const test_Length1: Length<[1, 2, 3, 4, 5]> = 5; | ||
const test_Length2: Length<[]> = 0; | ||
const test_Length3: Length<['a', 'b', 'c']> = 3; | ||
const test_Append1: TupleUtils.Append<[1, 2, 3, 4], 5> = [1, 2, 3, 4, 5]; | ||
const test_Append2: TupleUtils.Append<['a', true, undefined], 6> = ['a', true, undefined, 6]; | ||
const lest_Longest1: Longest<[1, 1, 1], [2, 2, 2]> = [1, 1, 1]; | ||
const lest_Longest2: Longest<[1, 1], [2, 2, 2]> = [2, 2, 2]; | ||
const lest_Longest3: Longest<[1, 1, 1, 1, 1], [2]> = [1, 1, 1, 1, 1]; | ||
const test_Append1: Append<[1, 2, 3, 4], 5> = [1, 2, 3, 4, 5]; | ||
const test_Append2: Append<['a', true, undefined], 6> = ['a', true, undefined, 6]; |
@@ -6,2 +6,3 @@ { | ||
"strictNullChecks": true, | ||
"isolatedModules": true, | ||
"forceConsistentCasingInFileNames": true, | ||
@@ -8,0 +9,0 @@ "lib": ["es5", "es6", "es2015", "es7", "es2016", "es2017", "es2018", "es2019", "es2020", "es2021", "es2022", "DOM"] |
/* eslint-disable @typescript-eslint/no-unused-vars, import/extensions, @typescript-eslint/no-namespace */ | ||
// INSPIRATION: https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f | ||
import { Longest } from './tuple'; | ||
/** | ||
@@ -9,109 +11,107 @@ * Type-level math operations | ||
declare namespace MathUtils { | ||
/** | ||
* Returns number by the given string representation | ||
* @typeParam T - any number | ||
* @requires TypeScript 4.8+ | ||
* @remarks | ||
* {@link https://github.com/microsoft/TypeScript/pull/48094 | Related TypeScript issue} | ||
* @example | ||
* const intValue: MathUtils.Parse<'123'> = 123; | ||
* const floatValue: MathUtils.Parse<'-56.78'> = -56.78; | ||
* const stringArg: MathUtils.Parse<123> = 123; | ||
*/ | ||
type Parse<T extends string | number> = T extends number ? T : T extends `${infer N extends number}` ? N : never; | ||
/** | ||
* Returns number by the given string representation | ||
* @typeParam T - any number | ||
* @requires TypeScript 4.8+ | ||
* @remarks | ||
* {@link https://github.com/microsoft/TypeScript/pull/48094 | Related TypeScript issue} | ||
* @example | ||
* const intValue: MathUtils.Parse<'123'> = 123; | ||
* const floatValue: MathUtils.Parse<'-56.78'> = -56.78; | ||
* const stringArg: MathUtils.Parse<123> = 123; | ||
*/ | ||
export type Parse<T extends string | number> = T extends number ? T : T extends `${infer N extends number}` ? N : never; | ||
/** @ignore */ | ||
type Digits = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; | ||
/** @ignore */ | ||
type Digits = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; | ||
/** @ignore */ | ||
type Carryings = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; | ||
/** @ignore */ | ||
type Carryings = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; | ||
/** @ignore */ | ||
type Units = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; | ||
/** @ignore */ | ||
type Units = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; | ||
/** @ignore */ | ||
type DigitSums = [ | ||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], | ||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], | ||
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11], | ||
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12], | ||
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13], | ||
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14], | ||
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15], | ||
[7, 8, 9, 10, 11, 12, 13, 14, 15, 16], | ||
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17], | ||
[9, 10, 11, 12, 13, 14, 15, 16, 17, 18] | ||
]; | ||
/** @ignore */ | ||
type DigitSums = [ | ||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], | ||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], | ||
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11], | ||
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12], | ||
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13], | ||
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14], | ||
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15], | ||
[7, 8, 9, 10, 11, 12, 13, 14, 15, 16], | ||
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17], | ||
[9, 10, 11, 12, 13, 14, 15, 16, 17, 18] | ||
]; | ||
/** @ignore */ | ||
type SplitDigits< | ||
Num extends string | number, | ||
A extends Digits[] = [] | ||
> = `${Num}` extends `${infer D extends Digits}${infer X}` ? SplitDigits<X, [D, ...A]> : [...A, '0']; | ||
/** @ignore */ | ||
export type SplitDigits< | ||
Num extends string | number, | ||
A extends Digits[] = [] | ||
> = `${Num}` extends `${infer D extends Digits}${infer X}` ? SplitDigits<X, [D, ...A]> : [...A, '0']; | ||
/** @ignore */ | ||
type SumDigits<A extends Digits = '0', B extends Digits = '0'> = DigitSums[A extends undefined | ||
? '0' | ||
: A][B extends undefined ? '0' : B]; | ||
/** @ignore */ | ||
export type SumDigits<A extends Digits = '0', B extends Digits = '0'> = DigitSums[A extends undefined | ||
? '0' | ||
: A][B extends undefined ? '0' : B]; | ||
/** @ignore */ | ||
type AddString< | ||
A extends string | number, | ||
B extends string | number, | ||
NumA extends Digits[] = SplitDigits<A>, | ||
NumB extends Digits[] = SplitDigits<B>, | ||
L extends Digits[] = TupleUtils.Longest<NumA, NumB> | ||
> = { | ||
[Index in keyof L]: SumDigits<NumA[Parse<Index>], NumB[Parse<Index>]>; | ||
}; | ||
/** @ignore */ | ||
export type AddString< | ||
A extends string | number, | ||
B extends string | number, | ||
NumA extends Digits[] = SplitDigits<A>, | ||
NumB extends Digits[] = SplitDigits<B>, | ||
L extends Digits[] = Longest<NumA, NumB> | ||
> = { | ||
[Index in keyof L]: SumDigits<NumA[Parse<Index>], NumB[Parse<Index>]>; | ||
}; | ||
/** @ignore */ | ||
type ToNumber<A, Result extends string = '', Carrying extends number = 0> = A extends [ | ||
infer D extends number, | ||
...infer Rest extends number[] | ||
] | ||
? ToNumber<Rest, `${Units[DigitSums[Units[D]][Carrying]]}${Result}`, D extends 9 ? Carrying : Carryings[D]> | ||
: Result; | ||
/** @ignore */ | ||
export type ToNumber<A, Result extends string = '', Carrying extends number = 0> = A extends [ | ||
infer D extends number, | ||
...infer Rest extends number[] | ||
] | ||
? ToNumber<Rest, `${Units[DigitSums[Units[D]][Carrying]]}${Result}`, D extends 9 ? Carrying : Carryings[D]> | ||
: Result; | ||
/** @ignore */ | ||
type Normalize<Str extends string> = Str extends `0${infer Num}` ? Normalize<Num> : Str; | ||
/** @ignore */ | ||
export type Normalize<Str extends string> = Str extends `0${infer Num}` ? Normalize<Num> : Str; | ||
/** @ignore */ | ||
type _Add_<A extends string | number, B extends string | number> = Parse<Normalize<ToNumber<AddString<A, B>>>>; | ||
/** @ignore */ | ||
type _Add_<A extends string | number, B extends string | number> = Parse<Normalize<ToNumber<AddString<A, B>>>>; | ||
/** @ignore */ | ||
type _Multiply_< | ||
A extends string | number, | ||
B extends string | number, | ||
Result extends number = 0, | ||
I extends number = 0 | ||
> = I extends Parse<A> ? Result : _Multiply_<Parse<A>, B, _Add_<Result, B>, _Add_<I, 1>>; | ||
/** @ignore */ | ||
type _Multiply_< | ||
A extends string | number, | ||
B extends string | number, | ||
Result extends number = 0, | ||
I extends number = 0 | ||
> = I extends Parse<A> ? Result : _Multiply_<Parse<A>, B, _Add_<Result, B>, _Add_<I, 1>>; | ||
/** | ||
* Addition of two positive integer values represented by either a number or a string format | ||
* @typeParam A - any positive integer number | ||
* @typeParam B - any positive integer number | ||
* @requires TypeScript 4.8+ | ||
* @remarks | ||
* The operation doesn't have any noticeable limitations | ||
* @example | ||
* const smallValue: MathUtils.Add<3, 4> = 7; | ||
* const bigValue: MathUtils.Add<9999999, 9999999> = 19999998; | ||
* const stringArgs: MathUtils.Add<'1234567890', '987654321'> = 2222222211; | ||
*/ | ||
type Add<A extends string | number, B extends string | number> = _Add_<A, B>; | ||
/** | ||
* Addition of two positive integer values represented by either a number or a string format | ||
* @typeParam A - any positive integer number | ||
* @typeParam B - any positive integer number | ||
* @requires TypeScript 4.8+ | ||
* @remarks | ||
* The operation doesn't have any noticeable limitations | ||
* @example | ||
* const smallValue: MathUtils.Add<3, 4> = 7; | ||
* const bigValue: MathUtils.Add<9999999, 9999999> = 19999998; | ||
* const stringArgs: MathUtils.Add<'1234567890', '987654321'> = 2222222211; | ||
*/ | ||
export type Add<A extends string | number, B extends string | number> = _Add_<A, B>; | ||
/** | ||
* Multiplies two positive integer values represented by either a number or a string format | ||
* @typeParam A - any positive integer number from 0 to 999 | ||
* @typeParam B - any positive integer number | ||
* @requires TypeScript 4.8+ | ||
* @remarks | ||
* The first argument can be 999 max because of a [hardcoded limit in TypeScript compiler](https://github.com/microsoft/TypeScript/pull/45711) | ||
* @example | ||
* const numberArgs: MathUtils.Multiply<78, 63> = 4914; | ||
* const stringArgs: MathUtils.Multiply<'999', '999'> = 998001; | ||
*/ | ||
type Multiply<A extends string | number, B extends string | number> = _Multiply_<A, B>; | ||
} | ||
/** | ||
* Multiplies two positive integer values represented by either a number or a string format | ||
* @typeParam A - any positive integer number from 0 to 999 | ||
* @typeParam B - any positive integer number | ||
* @requires TypeScript 4.8+ | ||
* @remarks | ||
* The first argument can be 999 max because of a [hardcoded limit in TypeScript compiler](https://github.com/microsoft/TypeScript/pull/45711) | ||
* @example | ||
* const numberArgs: MathUtils.Multiply<78, 63> = 4914; | ||
* const stringArgs: MathUtils.Multiply<'999', '999'> = 998001; | ||
*/ | ||
export type Multiply<A extends string | number, B extends string | number> = _Multiply_<A, B>; |
@@ -1,4 +0,6 @@ | ||
/* eslint-disable @typescript-eslint/no-namespace, @typescript-eslint/no-unused-vars */ | ||
/* eslint-disable @typescript-eslint/no-namespace, import/extensions, @typescript-eslint/no-unused-vars */ | ||
// INSPIRATION: https://lihautan.com/extract-parameters-type-from-string-literal-types-with-typescript/ | ||
import { Append } from './tuple'; | ||
/** | ||
@@ -8,72 +10,70 @@ * @requires Typescript: 4.5+ | ||
declare namespace StringUtils { | ||
/** @ignore */ | ||
type NotEmptyString<Str> = Str extends '' ? never : Str; | ||
/** @ignore */ | ||
type NotEmptyString<Str> = Str extends '' ? never : Str; | ||
/** | ||
* Removes leading white spaces (or the specified characters) from the given string | ||
* @typeParam Str - any string | ||
* @typeParam Spacer - any string | ||
* @example | ||
* const str1: StringUtils.TrimLeft<' abc'> = 'abc'; | ||
* const str2: StringUtils.TrimLeft<'*******abc', '*'> = 'abc'; | ||
*/ | ||
type TrimLeft<Str extends string, Spacer extends string = ' '> = Str extends `${Spacer}${infer Part}` | ||
? TrimLeft<Part, Spacer> | ||
: Str; | ||
/** | ||
* Removes leading white spaces (or the specified characters) from the given string | ||
* @typeParam Str - any string | ||
* @typeParam Spacer - any string | ||
* @example | ||
* const str1: StringUtils.TrimLeft<' abc'> = 'abc'; | ||
* const str2: StringUtils.TrimLeft<'*******abc', '*'> = 'abc'; | ||
*/ | ||
export type TrimLeft<Str extends string, Spacer extends string = ' '> = Str extends `${Spacer}${infer Part}` | ||
? TrimLeft<Part, Spacer> | ||
: Str; | ||
/** | ||
* Removes trailing white spaces (or the specified characters) from the given string | ||
* @typeParam Str - any string | ||
* @typeParam Spacer - optional string character | ||
* @example | ||
* const str1: StringUtils.TrimRight<'abc '> = 'abc'; | ||
* const str2: StringUtils.TrimRight<'abc*******', '*'> = 'abc'; | ||
*/ | ||
type TrimRight<Str extends string, Spacer extends string = ' '> = Str extends `${infer Part}${Spacer}` | ||
? TrimRight<Part, Spacer> | ||
: Str; | ||
/** | ||
* Removes trailing white spaces (or the specified characters) from the given string | ||
* @typeParam Str - any string | ||
* @typeParam Spacer - optional string character | ||
* @example | ||
* const str1: StringUtils.TrimRight<'abc '> = 'abc'; | ||
* const str2: StringUtils.TrimRight<'abc*******', '*'> = 'abc'; | ||
*/ | ||
export type TrimRight<Str extends string, Spacer extends string = ' '> = Str extends `${infer Part}${Spacer}` | ||
? TrimRight<Part, Spacer> | ||
: Str; | ||
/** | ||
* Removes leading and trailing white spaces (or the specified characters) from the given string | ||
* @typeParam Str - any string | ||
* @typeParam [Spacer] - optional string character | ||
* @example | ||
* const str1: StringUtils.Trim<' abc '> = 'abc'; | ||
* const str2: StringUtils.Trim<'*******abc*******', '*'> = 'abc'; | ||
*/ | ||
type Trim<Str extends string, Spacer extends string = ' '> = TrimLeft<TrimRight<Str, Spacer>, Spacer>; | ||
/** | ||
* Removes leading and trailing white spaces (or the specified characters) from the given string | ||
* @typeParam Str - any string | ||
* @typeParam [Spacer] - optional string character | ||
* @example | ||
* const str1: StringUtils.Trim<' abc '> = 'abc'; | ||
* const str2: StringUtils.Trim<'*******abc*******', '*'> = 'abc'; | ||
*/ | ||
export type Trim<Str extends string, Spacer extends string = ' '> = TrimLeft<TrimRight<Str, Spacer>, Spacer>; | ||
/** @ignore */ | ||
type _Split_< | ||
Str extends string, | ||
Spacer extends string = '\n', | ||
NoEmpty extends boolean = false, | ||
A extends string[] = [] | ||
> = Str extends `${infer PartA}${Spacer}${infer PartB}` | ||
? _Split_<Trim<PartB>, Spacer, NoEmpty, TupleUtils.Append<A, Trim<PartA>, NoEmpty>> | ||
: TupleUtils.Append<A, Trim<Str>, NoEmpty>; | ||
/** @ignore */ | ||
type _Split_< | ||
Str extends string, | ||
Spacer extends string = '\n', | ||
NoEmpty extends boolean = false, | ||
A extends string[] = [] | ||
> = Str extends `${infer PartA}${Spacer}${infer PartB}` | ||
? _Split_<Trim<PartB>, Spacer, NoEmpty, Append<A, Trim<PartA>, NoEmpty>> | ||
: Append<A, Trim<Str>, NoEmpty>; | ||
/** | ||
* Returns a tuple of substrings by splitting the string pattern by the given separator. | ||
* Additionally you can filter out empty string from the resulting list by specifying the third argument as `true` | ||
* @typeParam Str - any string | ||
* @typeParam Separator - any string character | ||
* @typeParam [NoEmpty] - optional flag | ||
* @example | ||
* const arr: StringUtils.Split<'a b c', ' '> = ['a', 'b', 'c']; | ||
*/ | ||
type Split<Str extends string, Separator extends string, NoEmpty extends boolean = false> = _Split_< | ||
Str, | ||
Separator, | ||
NoEmpty | ||
>; | ||
/** | ||
* Returns a tuple of substrings by splitting the string pattern by the given separator. | ||
* Additionally you can filter out empty string from the resulting list by specifying the third argument as `true` | ||
* @typeParam Str - any string | ||
* @typeParam Separator - any string character | ||
* @typeParam [NoEmpty] - optional flag | ||
* @example | ||
* const arr: StringUtils.Split<'a b c', ' '> = ['a', 'b', 'c']; | ||
*/ | ||
export type Split<Str extends string, Separator extends string, NoEmpty extends boolean = false> = _Split_< | ||
Str, | ||
Separator, | ||
NoEmpty | ||
>; | ||
/** | ||
* Transforms a tuple of strings into a union of string values | ||
* @typeParam A - any string tuple | ||
* @example | ||
* type StringUnion = StringUtils.Unique<['a', 'a', 'b', 'c', 'c']>; // "a" | "b" | "c" | ||
*/ | ||
type Unique<A extends string[]> = NotEmptyString<A[number]>; | ||
} | ||
/** | ||
* Transforms a tuple of strings into a union of string values | ||
* @typeParam A - any string tuple | ||
* @example | ||
* type StringUnion = StringUtils.Unique<['a', 'a', 'b', 'c', 'c']>; // "a" | "b" | "c" | ||
*/ | ||
export type Unique<A extends string[]> = NotEmptyString<A[number]>; |
@@ -6,37 +6,36 @@ /* eslint-disable @typescript-eslint/no-namespace, @typescript-eslint/no-unused-vars */ | ||
*/ | ||
declare namespace TupleUtils { | ||
/** | ||
* Returns length of the given tuple | ||
* @typeParam A - any tuple | ||
* @example | ||
* const length: TupleUtils.Length<[1, 2, 3, 4, 5]> = 5; | ||
*/ | ||
type Length<A extends unknown[]> = A extends { length: infer L } ? L : never; | ||
/** | ||
* Compares two tuples by their length and returns either the longest one of them | ||
* or the first one if they are the same length | ||
* @remarks | ||
* All items of both tuples must be defined in order for the operation to work properly | ||
* @typeParam A - any tuple without undefined items | ||
* @typeParam B - any tuple without undefined items | ||
* @example | ||
* const longest: TupleUtils.Longest<[1], [1, 2, 3]> = [1, 2, 3]; | ||
*/ | ||
type Longest<A extends unknown[], B extends unknown[]> = B[Length<A>] extends undefined ? A : B; | ||
/** | ||
* Returns length of the given tuple | ||
* @typeParam A - any tuple | ||
* @example | ||
* const length: TupleUtils.Length<[1, 2, 3, 4, 5]> = 5; | ||
*/ | ||
export type Length<A extends unknown[]> = A extends { length: infer L } ? L : never; | ||
/** | ||
* Appends new item to the given tuple. | ||
* Optionally you can ignore empty strings by specifying the third argument as `true` | ||
* @typeParam A - any tuple | ||
* @typeParam Item - any value | ||
* @typeParam [NoEmpty] - optional flag | ||
* @example | ||
* const arr: TupleUtils.Append<[1, 2, 3, 4], 5> = [1, 2, 3, 4, 5]; | ||
*/ | ||
type Append<A extends unknown[], Item, NoEmpty extends boolean = false> = NoEmpty extends true | ||
? Item extends '' | ||
? A | ||
: [...A, Item] | ||
: [...A, Item]; | ||
} | ||
/** | ||
* Compares two tuples by their length and returns either the longest one of them | ||
* or the first one if they are the same length | ||
* @remarks | ||
* All items of both tuples must be defined in order for the operation to work properly | ||
* @typeParam A - any tuple without undefined items | ||
* @typeParam B - any tuple without undefined items | ||
* @example | ||
* const longest: TupleUtils.Longest<[1], [1, 2, 3]> = [1, 2, 3]; | ||
*/ | ||
export type Longest<A extends unknown[], B extends unknown[]> = B[Length<A>] extends undefined ? A : B; | ||
/** | ||
* Appends new item to the given tuple. | ||
* Optionally you can ignore empty strings by specifying the third argument as `true` | ||
* @typeParam A - any tuple | ||
* @typeParam Item - any value | ||
* @typeParam [NoEmpty] - optional flag | ||
* @example | ||
* const arr: TupleUtils.Append<[1, 2, 3, 4], 5> = [1, 2, 3, 4, 5]; | ||
*/ | ||
export type Append<A extends unknown[], Item, NoEmpty extends boolean = false> = NoEmpty extends true | ||
? Item extends '' | ||
? A | ||
: [...A, Item] | ||
: [...A, Item]; |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1
58498
23
1648