├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .npmignore ├── .toolcheckrc.yaml ├── .travis.yml ├── LICENSE.md ├── README.md ├── index.ts ├── lib ├── index.ts └── utils.ts ├── package.json ├── pnpm-lock.yaml ├── renovate.json ├── spec ├── append.ts ├── compare-length.ts ├── concat-multiple.ts ├── concat.ts ├── drop.ts ├── fill-tuple.ts ├── filter.ts ├── first.ts ├── is-finite.ts ├── last.ts ├── longest-tuple.ts ├── prepend.ts ├── repeat.ts ├── reverse.ts ├── shortest-tuple.ts ├── slice-start-quantity.ts ├── sort-two-tuple.ts ├── tail.ts └── tslint.json ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | indent_size = 2 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: khai96_ 5 | open_collective: # Collective unavailable 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # disabled 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # This project 3 | .DS_Store 4 | .out 5 | .out.* 6 | out 7 | out.* 8 | *.*.map 9 | quick-test 10 | quick-test.* 11 | tmp 12 | temp 13 | tmp.* 14 | temp.* 15 | *.tmp 16 | *.temp 17 | *.tern-project 18 | *.tern-project.json 19 | *.js 20 | *.js.map 21 | *.d.ts 22 | /.vscode 23 | 24 | # Logs 25 | logs 26 | *.log 27 | npm-debug.log* 28 | 29 | # Runtime data 30 | pids 31 | *.pid 32 | *.seed 33 | 34 | # Directory for instrumented libs generated by jscoverage/JSCover 35 | lib-cov 36 | 37 | # Coverage directory used by tools like istanbul 38 | coverage 39 | 40 | # nyc test coverage 41 | .nyc_output 42 | 43 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 44 | .grunt 45 | 46 | # node-waf configuration 47 | .lock-wscript 48 | 49 | # Compiled binary addons (http://nodejs.org/api/addons.html) 50 | build/Release 51 | 52 | # Dependency directories 53 | node_modules 54 | jspm_packages 55 | 56 | # Optional npm cache directory 57 | .npm 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Byte-compiled / optimized / DLL files 63 | __pycache__/ 64 | *.py[cod] 65 | *$py.class 66 | 67 | # C extensions 68 | *.so 69 | 70 | # Distribution / packaging 71 | .Python 72 | build/ 73 | develop-eggs/ 74 | dist/ 75 | downloads/ 76 | eggs/ 77 | .eggs/ 78 | lib32/ 79 | lib64/ 80 | parts/ 81 | sdist/ 82 | var/ 83 | wheels/ 84 | *.egg-info/ 85 | .installed.cfg 86 | *.egg 87 | 88 | # PyInstaller 89 | # Usually these files are written by a python script from a template 90 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 91 | *.manifest 92 | *.spec 93 | 94 | # Installer logs 95 | pip-log.txt 96 | pip-delete-this-directory.txt 97 | 98 | # Unit test / coverage reports 99 | htmlcov/ 100 | .tox/ 101 | .coverage 102 | .coverage.* 103 | .cache 104 | nosetests.xml 105 | coverage.xml 106 | *.cover 107 | .hypothesis/ 108 | 109 | # Translations 110 | *.mo 111 | *.pot 112 | 113 | # Django stuff: 114 | *.log 115 | local_settings.py 116 | 117 | # Flask stuff: 118 | instance/ 119 | .webassets-cache 120 | 121 | # Scrapy stuff: 122 | .scrapy 123 | 124 | # Sphinx documentation 125 | docs/_build/ 126 | 127 | # PyBuilder 128 | target/ 129 | 130 | # Jupyter Notebook 131 | .ipynb_checkpoints 132 | 133 | # pyenv 134 | .python-version 135 | 136 | # celery beat schedule file 137 | celerybeat-schedule 138 | 139 | # SageMath parsed files 140 | *.sage.py 141 | 142 | # Environments 143 | .env 144 | .venv 145 | env/ 146 | venv/ 147 | ENV/ 148 | 149 | # Spyder project settings 150 | .spyderproject 151 | .spyproject 152 | 153 | # Rope project settings 154 | .ropeproject 155 | 156 | # mkdocs documentation 157 | /site 158 | 159 | # mypy 160 | .mypy_cache/ 161 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | 2 | *.log 3 | quick-test 4 | test 5 | tmp 6 | temp 7 | tmp.* 8 | temp.* 9 | *.tmp 10 | *.temp 11 | *.sh 12 | *.tern-project* 13 | *.editorconfig* 14 | *.eslintrc* 15 | .git* 16 | /.travis.yml 17 | /appveyor.yml 18 | /circle.yml 19 | /sh 20 | docs 21 | yarn.lock 22 | package-lock.json 23 | shrinkwrap* 24 | renovate* 25 | tsconfig* 26 | tslint* 27 | *.ts 28 | !*.d.ts 29 | spec* 30 | *.js.map 31 | *.d.ts.map 32 | /TODO 33 | .toolcheckrc* 34 | -------------------------------------------------------------------------------- /.toolcheckrc.yaml: -------------------------------------------------------------------------------- 1 | names: 2 | - pnpm 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | branches: 2 | except: 3 | - draft 4 | - tmp 5 | - /.*\.(draft|tmp)$/ 6 | - /^(draft|tmp)\..*/ 7 | 8 | language: node_js 9 | 10 | node_js: 11 | - '10' 12 | 13 | cache: 14 | directories: 15 | - $HOME/.pnpm-store 16 | - $HOME/.npm 17 | - $HOME/.nvm 18 | - $HOME/.node-gyp 19 | - $HOME/.node_libraries 20 | 21 | before_install: 22 | - curl -L https://unpkg.com/@pnpm/self-installer | node 23 | - pnpm --version 24 | 25 | install: 26 | - pnpm install 27 | 28 | script: 29 | - pnpm test 30 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright © 2018 Hoàng Văn Khải 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Tuple 2 | 3 | Generics to work with tuples in TypeScript 4 | 5 | ## Requirements 6 | 7 | * TypeScript ≥ 4.1.0 8 | 9 | ## Usage 10 | 11 | ### `IsFinite` 12 | 13 | ```typescript 14 | import { IsFinite } from 'typescript-tuple' 15 | 16 | type Foo = IsFinite<[0, 1, 2]> // Expect: true 17 | const foo: Foo = true 18 | 19 | type Bar = IsFinite<[0, 1, 2, ...number[]]> // Expect: false 20 | const bar: Bar = false 21 | 22 | type Baz = IsFinite<[0, 1, 2], 'finite', 'infinite'> // Expect: 'finite' 23 | const baz: Baz = 'finite' 24 | ``` 25 | 26 | ### `First` 27 | 28 | ```typescript 29 | import { First } from 'typescript-tuple' 30 | type Foo = First<['a', 'b', 'c']> // Expect: 'a' 31 | const foo: Foo = 'a' 32 | ``` 33 | 34 | ### `Last` 35 | 36 | ```typescript 37 | import { Last } from 'typescript-tuple' 38 | type Foo = Last<['a', 'b', 'c']> // Expect: 'c' 39 | const foo: Foo = 'c' 40 | ``` 41 | 42 | ### `Tail` 43 | 44 | ```typescript 45 | import { Tail } from 'typescript-tuple' 46 | type Foo = Tail<['a', 'b', 'c']> // Expect: ['b', 'c'] 47 | const foo: Foo = ['b', 'c'] 48 | ``` 49 | 50 | ### `Append` 51 | 52 | ```typescript 53 | import { Append } from 'typescript-tuple' 54 | type Foo = Append<['a', 'b', 'c'], 'x'> // Expect: ['a', 'b', 'c', 'x'] 55 | const foo: Foo = ['a', 'b', 'c', 'x'] 56 | ``` 57 | 58 | ### `Prepend` 59 | 60 | ```typescript 61 | import { Prepend } from 'typescript-tuple' 62 | type Foo = Prepend<['a', 'b', 'c'], 'x'> // Expect: ['x', 'a', 'b', 'c'] 63 | const foo: Foo = ['x', 'a', 'b', 'c'] 64 | ``` 65 | 66 | ### `Reverse` 67 | 68 | ```typescript 69 | import { Reverse } from 'typescript-tuple' 70 | type Foo = Reverse<['a', 'b', 'c']> // Expect: ['c', 'b', 'a'] 71 | const foo: Foo = ['c', 'b', 'a'] 72 | ``` 73 | 74 | ### `Concat` 75 | 76 | ```typescript 77 | import { Concat } from 'typescript-tuple' 78 | type Foo = Concat<['a', 'b', 'c'], [0, 1, 2]> // Expect ['a', 'b', 'c', 0, 1, 2] 79 | const foo: Foo = ['a', 'b', 'c', 0, 1, 2] 80 | ``` 81 | 82 | ### `Repeat` 83 | 84 | ```typescript 85 | import { Repeat } from 'typescript-tuple' 86 | 87 | // Basic 88 | type Foo = Repeat<'x', 5> // Expect ['x', 'x', 'x', 'x', 'x'] 89 | const foo: Foo = ['x', 'x', 'x', 'x', 'x'] 90 | 91 | // Using union 92 | type Bar = Repeat<'x', 1 | 3 | 4> // Expect ['x'] | ['x', 'x', 'x'] | ['x', 'x', 'x', 'x'] 93 | const bar1: Bar = ['x'] 94 | const bar3: Bar = ['x', 'x', 'x'] 95 | const bar4: Bar = ['x', 'x', 'x', 'x'] 96 | 97 | // Using ambiguous 'number' type 98 | type Baz = Repeat<'x', number> // Expect 'x'[] 99 | const baz: Baz = Array() 100 | ``` 101 | 102 | **NOTES:** 103 | 104 | * Due to TypeScript design limitations, using floating point numbers and negative numbers might lead to infinite loop within TSC compiler, avoid doing this. 105 | 106 | ### `ConcatMultiple` 107 | 108 | ```typescript 109 | import { ConcatMultiple } from 'typescript-tuple' 110 | type Foo = ConcatMultiple<[[], ['a'], ['b', 'c']]> // Expect ['a', 'b', 'c'] 111 | const foo: Foo = ['a', 'b', 'c'] 112 | ``` 113 | 114 | ### `Drop` 115 | 116 | ```typescript 117 | import { Drop } from 'typescript-tuple' 118 | 119 | type Foo = Drop<[0, 1, 2, 3, 4], 2> // Expect [2, 3, 4] 120 | const foo: Foo = [2, 3, 4] 121 | 122 | type Bar = Drop<[0, 1, 2, 3, 4, ...number[]], 2> // Expect [2, 3, 4, ...number[]] 123 | const bar: Bar = [2, 3, 4] 124 | 125 | type Baz = Drop<[0, 1, 2, 3, 4], 10> // Expect [] 126 | const baz: Baz = [2, 3, 4] 127 | 128 | type Qux = Drop<[0, 1, 2, 3, 4, ...number[]], 10> // Expect number[] 129 | const qux: Qux = [2, 3, 4] 130 | ``` 131 | 132 | ### `SliceStartQuantity` 133 | 134 | ```typescript 135 | import { SliceStartQuantity } from 'typescript-tuple' 136 | type Foo = SliceStartQuantity<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 4> // Expect [2, 3, 4, 5] 137 | const foo: Foo = [2, 3, 4, 5] 138 | ``` 139 | 140 | ### `FillTuple` 141 | 142 | ```typescript 143 | import { FillTuple } from 'typescript-tuple' 144 | type Foo = FillTuple<[0, 1, 2, 3], 'r'> 145 | const foo: Foo = ['r', 'r', 'r', 'r'] 146 | ``` 147 | 148 | ### `CompareLength` 149 | 150 | ```typescript 151 | import { CompareLength } from 'typescript-tuple' 152 | 153 | type Foo = CompareLength<[0, 1, 2], ['a', 'b', 'c']> // Expect: 'equal' 154 | const foo: Foo = 'equal' 155 | 156 | type Bar = CompareLength<[0, 1], ['a', 'b', 'c', 'd']> // Expect: 'shorterLeft' 157 | const bar: Bar = 'shorterLeft' 158 | 159 | type Baz = CompareLength<[0, 1, 2, 3], ['a', 'b']> // Expect: 'shorterRight' 160 | const baz: Baz = 'shorterRight' 161 | ``` 162 | 163 | ### `SortTwoTuple` 164 | 165 | ```typescript 166 | import { SortTwoTuple } from 'typescript-tuple' 167 | 168 | type Foo = SortTwoTuple<[0, 1], ['a', 'b', 'c', 'd']> // Expect: [[0, 1], ['a', 'b', 'c', 'd']] 169 | const foo: Foo = [[0, 1], ['a', 'b', 'c', 'd']] 170 | 171 | type Bar = SortTwoTuple<[0, 1, 2, 3], ['a', 'b']> // Expect: [['a', 'b'], [0, 1, 2, 3]] 172 | const bar: Bar = [['a', 'b'], [0, 1, 2, 3]] 173 | 174 | type Baz = SortTwoTuple<[0, 1, 2], ['a', 'b', 'c', 'd']> // Expect: [[0, 1, 2], ['a', 'b', 'c']] 175 | const baz: Baz = [[0, 1], 3, ['a', 'b', 'c']] 176 | 177 | type Qux = SortTwoTuple<[0, 1, 2], ['a', 'b', 'c', 'd'], 'EQUAL'> // Expect: 'EQUAL' 178 | const qux: Qux = 'EQUAL' 179 | ``` 180 | 181 | ### `ShortestTuple` 182 | 183 | ```typescript 184 | import { ShortestTuple } from 'typescript-tuple' 185 | 186 | type Foo = ShortestTuple<[[0, 1, 2], [false, true], ['a', 'b', 'c', 'd']]> // Expect: [false, true] 187 | const foo: Foo = [false, true] 188 | 189 | type Bar = ShortestTuple<[[0, 1, 2], ['a', 'b', 'c'], ...[false, true][]]> // Expect: [false, true] 190 | const bar: Bar = [false, true] 191 | ``` 192 | 193 | ### `LongestTuple` 194 | 195 | ```typescript 196 | import { LongestTuple } from 'typescript-tuple' 197 | 198 | type Foo = LongestTuple<[[0, 1, 2, 3], [false, true], ['a']]> // Expect: [0, 1, 2, 3] 199 | const foo: Foo = [0, 1, 2, 3] 200 | 201 | type Bar = LongestTuple<[[], [false, true], ...[0, 1, 2][]]> // Expect: [0, 1, 2] 202 | const bar: Bar = [0, 1, 2] 203 | ``` 204 | 205 | ### `FilterTuple` 206 | 207 | ```typescript 208 | import { FilterTuple } from 'typescript-tuple' 209 | 210 | type Foo = FilterTuple<[1, '1'], number> // Expect: [1] 211 | const foo: Foo = [1] 212 | 213 | type Bar = FilterTuple<[1, '1', null, true], 1 | '1' | true> // Expect: [1, '1', true] 214 | const bar: Bar = [1, '1', true] 215 | ``` 216 | 217 | ## License 218 | 219 | [MIT](https://git.io/fA2d9) @ [Hoàng Văn Khải](https://github.com/KSXGitHub) 220 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib' 2 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | import * as utils from './utils' 2 | 3 | /** 4 | * Choose type base on whether or not a tuple is finite 5 | * @example IsFinite<[0, 1, 2]> → true 6 | * @example IsFinite<[0, 1, 2, ...number[]]> → false 7 | * @example IsFinite<[0], 'Finite', 'Infinite'> → 'Finite' 8 | * @example IsFinite<[0, ...number[]], 'Finite', 'Infinite'> → Infinite 9 | */ 10 | export type IsFinite = 11 | utils.IsFinite 12 | 13 | /** 14 | * Get type of first element 15 | * @example First<[0, 1, 2]> → 0 16 | */ 17 | export type First = Tuple[0] 18 | 19 | /** 20 | * Get type of last element 21 | * @example Last<[0, 1, 2]> → 2 22 | */ 23 | export type Last = utils.Last 24 | 25 | /** 26 | * Drop the first element 27 | * @example Tail<[0, 1, 2, 3]> → [1, 2, 3] 28 | */ 29 | export type Tail = utils.Tail 30 | 31 | /** 32 | * Add an element to the end of a tuple 33 | * @example Append<[0, 1, 2], 'new'> → [0, 1, 2, 'new'] 34 | */ 35 | export type Append = Reverse, Addend>> 36 | 37 | /** 38 | * Add an element to the beginning of a tuple 39 | * @example Prepend<[0, 1, 2], 'new'> → ['new', 0, 1, 2] 40 | */ 41 | export type Prepend = utils.Prepend 42 | 43 | /** 44 | * Reverse a tuple 45 | * @example Reverse<[0, 1, 2]> → [2, 1, 0] 46 | */ 47 | export type Reverse = utils.Reverse 48 | 49 | /** 50 | * Concat two tuple into one 51 | * @example Concat<[0, 1, 2], ['a', 'b', 'c']> → [0, 1, 2, 'a', 'b', 'c'] 52 | */ 53 | export type Concat = utils.Concat 54 | 55 | /** 56 | * Repeat a certain type into a tuple 57 | * @example Repeat<'foo', 4> → ['foo', 'foo', 'foo', 'foo'] 58 | * @warning To avoid potential infinite loop, Count must be an integer greater than or equal to 0 59 | */ 60 | export type Repeat = utils.Repeat 61 | 62 | /** 63 | * Concat multiple tuples 64 | * @example ConcatMultiple<[], [0], [1, 2], [3, 4, 5]> → [0, 1, 2, 3, 4, 5] 65 | */ 66 | export type ConcatMultiple = utils.ConcatMultiple 67 | 68 | /** 69 | * Drop `Quantity` first elements of a tuple 70 | * @example Drop<['a', 'b', 'c', 'd', 'e'], 2> → ['c', 'd', 'e'] 71 | * @example Drop<['a', 'b', 'c', 'd', 'e', ...string[]], 2> → ['c', 'd', 'e', ...string[]] 72 | * @example Drop<['a', 'b', 'c', 'd', 'e', ...string[]], 10> → string[] 73 | */ 74 | export type Drop = utils.Drop 75 | 76 | /** 77 | * Slice a tuple 78 | * @example SliceStartQuantity<[0, 1, 2, 3, 4, 5, 6], 2, 3> → [2, 3, 4] 79 | * @example SliceStartQuantity<[0, 1, 2, 3, 4, 5, 6], 2, 9> → [2, 3, 4, 5, 6] 80 | */ 81 | export type SliceStartQuantity< 82 | Tuple extends any[], 83 | Start extends number, 84 | Quantity extends number 85 | > = utils.SliceStartQuantity 86 | 87 | /** 88 | * Fill a tuple of types 89 | * @example FillTuple<[0, 1, 2], 'x'> → ['x', 'x', 'x'] 90 | * @example FillTuple → 'x'[] 91 | */ 92 | export type FillTuple = utils.FillTuple 93 | 94 | /** 95 | * Compare length of two tuple 96 | * @example CompareLength<[0, 1, 2], ['a', 'b', 'c']> → 'equal' 97 | * @example CompareLength<[0, 1], ['a', 'b', 'c']> → 'shorterLeft' 98 | * @example CompareLength<[0, 1, 2], ['a', 'b']> → 'shorterRight' 99 | */ 100 | export type CompareLength = utils.CompareLength 101 | 102 | /** 103 | * Sort two tuples in order of [shorter, longer] 104 | * @example SortTwoTuple<[0, 1, 2, 3], ['a', 'b']> → [['a', 'b'], [0, 1, 2, 3]] 105 | * @example SortTwoTuple<[0, 1], ['a', 'b', 'c', 'd']> → [[0, 1], ['a', 'b', 'c', 'd']] 106 | * @example SortTwoTuple<[0, 1, 2], ['a', 'b', 'c']> → [[0, 1, 2], ['a', 'b', 'c']] 107 | * @example SortTwoTuple<[0, 1, 2], ['a', 'b', 'c'], 'EQUAL'> → 'EQUAL' 108 | */ 109 | export type SortTwoTuple = 110 | utils.SortTwoTuple 111 | 112 | /** 113 | * Find shortest tuple in a set of tuples 114 | * @example ShortestTuple<[[0, 1, 2], [true, false], ['a', 'b', 'c', 'd']]> → [true, false] 115 | */ 116 | export type ShortestTuple = utils.ShortestTuple 117 | 118 | /** 119 | * Find shortest tuple in a set of tuples 120 | * @example LongestTuple<[[0, 1, 2], [true, false], ['a', 'b', 'c', 'd']]> → ['a', 'b', 'c', 'd'] 121 | */ 122 | export type LongestTuple = utils.LongestTuple 123 | 124 | /** 125 | * Filter tuple elements thats match the mask 126 | * @example FilterTuple<[1, 2, true, '3'], string | number> → [1, 2, "3"] 127 | */ 128 | export type FilterTuple = utils.FilterTuple 129 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | export type IsFinite = 2 | Tuple extends [] ? Finite : 3 | Tuple extends Array ? 4 | Element[] extends Tuple ? 5 | Infinite 6 | : Tuple extends [any, ...infer Rest] 7 | ? IsFinite 8 | : never 9 | : never 10 | 11 | export type _SplitInfiniteTuple = 12 | Tuple extends Array ? 13 | Element[] extends Tuple ? [Tuple, Holder] : 14 | Tuple extends [infer First, ...infer Rest] ? 15 | _SplitInfiniteTuple> 16 | : never 17 | : never 18 | 19 | export type First = 20 | Tuple extends [any, ...any[]] ? Tuple[0] : Default 21 | 22 | export type Last = 23 | Tuple extends [] ? Default : 24 | Tuple extends [infer SoleElement] ? SoleElement : 25 | Tuple extends Array ? 26 | Element[] extends Tuple ? Element : 27 | Tuple extends [any, ...infer Next] ? Last : Default 28 | : never 29 | 30 | export type Tail = 31 | ((...args: Tuple) => any) extends ((_: any, ..._1: infer Rest) => any) 32 | ? Rest 33 | : never 34 | 35 | export type Prepend = [Addend, ...Tuple] 36 | 37 | export type Reverse = { 38 | empty: Prefix, 39 | nonEmpty: Tuple extends [infer First, ...infer Next] 40 | ? Reverse> 41 | : never 42 | infinite: { 43 | ERROR: 'Cannot reverse an infinite tuple' 44 | CODENAME: 'InfiniteTuple' 45 | } 46 | }[ 47 | Tuple extends [any, ...any[]] 48 | ? IsFinite 49 | : 'empty' 50 | ] 51 | 52 | export type Concat = [...Left, ...Right] 53 | 54 | export type Repeat = 55 | Count extends never ? never : 56 | number extends Count ? Type[] : 57 | Holder['length'] extends Count ? // It is possible for Count to be a union 58 | Count extends Holder['length'] ? // Make sure that Count is not a union 59 | Holder 60 | // Count is a union 61 | : Count extends Holder['length'] | infer Rest ? 62 | Rest extends number ? 63 | Repeat | Repeat 64 | : never 65 | : never 66 | // Count is not Holder['length'] 67 | : Repeat> 68 | 69 | export type ConcatMultiple = { 70 | empty: [] 71 | nonEmpty: ((..._: Reverse) => any) extends ((_: infer Last, ..._1: infer ReversedRest) => any) ? 72 | Last extends any[] ? 73 | ReversedRest extends any[][] ? 74 | Concat>, Last> : 75 | never : 76 | never : 77 | never 78 | infinite: { 79 | ERROR: 'TupleSet is not finite', 80 | CODENAME: 'InfiniteTupleSet' & 'Infinite' 81 | } 82 | }[ 83 | TupleSet extends [] ? 'empty' : IsFinite 84 | ] 85 | 86 | export type Drop = 87 | [ 88 | any[] extends Tuple ? true : false, 89 | number extends Quantity ? true : false 90 | ] extends true[] ? Tuple : 91 | Tuple extends [] ? Tuple : 92 | Quantity extends Count['length'] ? Tuple : 93 | ((...args: Tuple) => any) extends ((_: any, ..._1: infer Rest) => any) 94 | ? Drop> 95 | : never 96 | 97 | export type SliceStartQuantity< 98 | Tuple extends any[], 99 | Start extends number, 100 | Quantity extends number, 101 | Holder extends any[] = [], 102 | Count extends any[] = [] 103 | > = 104 | Tuple extends [] ? Reverse : 105 | Quantity extends Holder['length'] ? Reverse : 106 | Start extends Count['length'] ? 107 | Tuple extends [infer First, ...infer Rest] 108 | ? SliceStartQuantity, Count> 109 | : never 110 | : SliceStartQuantity< 111 | Tail, 112 | Start, 113 | Quantity, 114 | Holder, 115 | Prepend 116 | > 117 | 118 | export type FillTuple = { 119 | empty: Holder 120 | nonEmpty: Tuple extends [any, ...infer Rest] 121 | ? FillTuple> 122 | : never 123 | infinite: Replacement[] 124 | }[ 125 | Tuple extends [] ? 'empty' : IsFinite 126 | ] 127 | 128 | export type CompareLength = 129 | Left['length'] extends Right['length'] ? 'equal' : 130 | Left extends [] ? 'shorterLeft' : 131 | Right extends [] ? 'shorterRight' : 132 | CompareLength, Tail> 133 | 134 | export type SortTwoTuple = { 135 | equal: WhenEqual 136 | shorterLeft: [Left, Right] 137 | shorterRight: [Right, Left] 138 | }[CompareLength] 139 | 140 | export type ShortestTuple = 141 | TupleSet extends [] ? Shortest : 142 | ((..._: TupleSet) => any) extends ((_: infer Head, ..._1: infer Tail) => any) ? 143 | Tail extends any[] ? 144 | Head extends any[] ? 145 | Tail extends Head[] 146 | ? SortTwoTuple[0] 147 | : ShortestTuple[0]> 148 | : never 149 | : never 150 | : never 151 | 152 | export type LongestTuple = { 153 | empty: Longest 154 | nonEmpty: ((..._: TupleSet) => any) extends ((_: infer Head, ..._1: infer Tail) => any) ? 155 | Tail extends any[] ? 156 | Longest extends any[] ? 157 | Head extends any[] ? 158 | Tail extends Head[] 159 | ? SortTwoTuple[1] 160 | : LongestTuple[1]> 161 | : never 162 | : never 163 | : never 164 | : never 165 | }[ 166 | TupleSet extends [] ? 'empty' : 'nonEmpty' 167 | ] 168 | 169 | export type FilterTuple = ConcatMultiple<{ 170 | [K in keyof Tuple]: Tuple[K] extends Mask ? [Tuple[K]] : [] 171 | }> 172 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-tuple", 3 | "version": "5.0.1", 4 | "description": "Generics to work with tuples in TypeScript", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "pnpm run lint && tsc", 8 | "clean": "clean-typescript-build .", 9 | "lint": "tslint -p .", 10 | "lint:fix": "pnpm run lint -- --fix", 11 | "test:types": "tsc --noEmit", 12 | "prepublishOnly": "pnpm run build", 13 | "postpublish": "pnpm run clean", 14 | "test": "pnpm run lint && pnpm run test:types" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/ksxnodemodules/typescript-tuple.git" 19 | }, 20 | "keywords": [ 21 | "generic", 22 | "tuple", 23 | "typescript" 24 | ], 25 | "author": "Hoàng Văn Khải ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/ksxnodemodules/typescript-tuple/issues" 29 | }, 30 | "homepage": "https://github.com/ksxnodemodules/typescript-tuple#readme", 31 | "dependencies": { 32 | "typescript-compare": "^0.0.2" 33 | }, 34 | "devDependencies": { 35 | "typescript": "~4.2.0", 36 | "tslint": "^6.1.3", 37 | "tslint-config-standard": "^9.0.0", 38 | "static-type-assert": "^4.0.1", 39 | "toolcheck": "^0.1.4", 40 | "clean-typescript-build": "^0.1.5" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | typescript-compare: 0.0.2 3 | devDependencies: 4 | clean-typescript-build: 0.1.5 5 | static-type-assert: 4.0.1_typescript@4.2.3 6 | toolcheck: 0.1.4 7 | tslint: 6.1.3_typescript@4.2.3 8 | tslint-config-standard: 9.0.0_tslint@6.1.3+typescript@4.2.3 9 | typescript: 4.2.3 10 | lockfileVersion: 5.2 11 | packages: 12 | /@babel/code-frame/7.10.4: 13 | dependencies: 14 | '@babel/highlight': 7.10.4 15 | dev: true 16 | resolution: 17 | integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== 18 | /@babel/helper-validator-identifier/7.10.4: 19 | dev: true 20 | resolution: 21 | integrity: sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== 22 | /@babel/highlight/7.10.4: 23 | dependencies: 24 | '@babel/helper-validator-identifier': 7.10.4 25 | chalk: 2.4.2 26 | js-tokens: 4.0.0 27 | dev: true 28 | resolution: 29 | integrity: sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== 30 | /@tsfun/array/0.0.0: 31 | dependencies: 32 | '@types/node': 13.13.32 33 | tslib: 1.14.1 34 | dev: true 35 | resolution: 36 | integrity: sha512-y18KD65Ba1a7jXJ8PBIGjfkCtR32wd0XOPaV5D8z9uBiNE+pIF0PCnHKVHZ4+GcaRa/Y7HkTWJxmcjs283ggmw== 37 | /@types/cosmiconfig/5.0.3: 38 | dependencies: 39 | '@types/node': 12.19.6 40 | dev: true 41 | resolution: 42 | integrity: sha512-HgTGG7X5y9pLl3pixeo2XtDEFD8rq2EuH+S4mK6teCnAwWMucQl6v1D43hI4Uw1VJh6nu59lxLkqXHRl4uwThA== 43 | /@types/fs-extra/8.1.1: 44 | dependencies: 45 | '@types/node': 13.13.32 46 | dev: true 47 | resolution: 48 | integrity: sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w== 49 | /@types/node/12.19.6: 50 | dev: true 51 | resolution: 52 | integrity: sha512-U2VopDdmBoYBmtm8Rz340mvvSz34VgX/K9+XCuckvcLGMkt3rbMX8soqFOikIPlPBc5lmw8By9NUK7bEFSBFlQ== 53 | /@types/node/13.13.32: 54 | dev: true 55 | resolution: 56 | integrity: sha512-sPBvDnrwZE1uePhkCEyI/qQlgZM5kePPAhHIFDWNsOrWBFRBOk3LKJYmVCLeLZlL9Ub/FzMJb31OTWCg2F+06g== 57 | /@types/parse-json/4.0.0: 58 | dev: true 59 | resolution: 60 | integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== 61 | /@types/yargs-parser/15.0.0: 62 | dev: true 63 | resolution: 64 | integrity: sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== 65 | /@types/yargs/15.0.10: 66 | dependencies: 67 | '@types/yargs-parser': 15.0.0 68 | dev: true 69 | resolution: 70 | integrity: sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ== 71 | /ansi-regex/5.0.0: 72 | dev: true 73 | engines: 74 | node: '>=8' 75 | resolution: 76 | integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 77 | /ansi-styles/3.2.1: 78 | dependencies: 79 | color-convert: 1.9.3 80 | dev: true 81 | engines: 82 | node: '>=4' 83 | resolution: 84 | integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 85 | /ansi-styles/4.3.0: 86 | dependencies: 87 | color-convert: 2.0.1 88 | dev: true 89 | engines: 90 | node: '>=8' 91 | resolution: 92 | integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 93 | /argparse/1.0.10: 94 | dependencies: 95 | sprintf-js: 1.0.3 96 | dev: true 97 | resolution: 98 | integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 99 | /balanced-match/1.0.0: 100 | dev: true 101 | resolution: 102 | integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 103 | /brace-expansion/1.1.11: 104 | dependencies: 105 | balanced-match: 1.0.0 106 | concat-map: 0.0.1 107 | dev: true 108 | resolution: 109 | integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 110 | /builtin-modules/1.1.1: 111 | dev: true 112 | engines: 113 | node: '>=0.10.0' 114 | resolution: 115 | integrity: sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= 116 | /callsites/3.1.0: 117 | dev: true 118 | engines: 119 | node: '>=6' 120 | resolution: 121 | integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 122 | /camelcase/5.3.1: 123 | dev: true 124 | engines: 125 | node: '>=6' 126 | resolution: 127 | integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 128 | /chalk/2.4.2: 129 | dependencies: 130 | ansi-styles: 3.2.1 131 | escape-string-regexp: 1.0.5 132 | supports-color: 5.5.0 133 | dev: true 134 | engines: 135 | node: '>=4' 136 | resolution: 137 | integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 138 | /clean-typescript-build/0.1.5: 139 | dependencies: 140 | '@tsfun/array': 0.0.0 141 | '@types/fs-extra': 8.1.1 142 | '@types/node': 13.13.32 143 | '@types/yargs': 15.0.10 144 | fs-extra: 8.1.0 145 | fs-tree-utils: 0.1.8 146 | tslib: 1.14.1 147 | yargs: 15.4.1 148 | dev: true 149 | engines: 150 | node: '>= 8.9.0' 151 | hasBin: true 152 | resolution: 153 | integrity: sha512-WeSaaZqVBKwo1tFLSRA4CJiay2SX+ygR6DBbmt16kIhEhuXbYJ92S/wKoimb4bKpC2ThBeo0nUYqyx4qttmyjw== 154 | /cliui/6.0.0: 155 | dependencies: 156 | string-width: 4.2.0 157 | strip-ansi: 6.0.0 158 | wrap-ansi: 6.2.0 159 | dev: true 160 | resolution: 161 | integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== 162 | /color-convert/1.9.3: 163 | dependencies: 164 | color-name: 1.1.3 165 | dev: true 166 | resolution: 167 | integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 168 | /color-convert/2.0.1: 169 | dependencies: 170 | color-name: 1.1.4 171 | dev: true 172 | engines: 173 | node: '>=7.0.0' 174 | resolution: 175 | integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 176 | /color-name/1.1.3: 177 | dev: true 178 | resolution: 179 | integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 180 | /color-name/1.1.4: 181 | dev: true 182 | resolution: 183 | integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 184 | /commander/2.20.3: 185 | dev: true 186 | resolution: 187 | integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 188 | /concat-map/0.0.1: 189 | dev: true 190 | resolution: 191 | integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 192 | /cosmiconfig/6.0.0: 193 | dependencies: 194 | '@types/parse-json': 4.0.0 195 | import-fresh: 3.2.2 196 | parse-json: 5.1.0 197 | path-type: 4.0.0 198 | yaml: 1.10.0 199 | dev: true 200 | engines: 201 | node: '>=8' 202 | resolution: 203 | integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== 204 | /decamelize/1.2.0: 205 | dev: true 206 | engines: 207 | node: '>=0.10.0' 208 | resolution: 209 | integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 210 | /diff/4.0.2: 211 | dev: true 212 | engines: 213 | node: '>=0.3.1' 214 | resolution: 215 | integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 216 | /doctrine/0.7.2: 217 | dependencies: 218 | esutils: 1.1.6 219 | isarray: 0.0.1 220 | dev: true 221 | engines: 222 | node: '>=0.10.0' 223 | resolution: 224 | integrity: sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM= 225 | /emoji-regex/8.0.0: 226 | dev: true 227 | resolution: 228 | integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 229 | /error-ex/1.3.2: 230 | dependencies: 231 | is-arrayish: 0.2.1 232 | dev: true 233 | resolution: 234 | integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 235 | /escape-string-regexp/1.0.5: 236 | dev: true 237 | engines: 238 | node: '>=0.8.0' 239 | resolution: 240 | integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 241 | /esprima/4.0.1: 242 | dev: true 243 | engines: 244 | node: '>=4' 245 | hasBin: true 246 | resolution: 247 | integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 248 | /esutils/1.1.6: 249 | dev: true 250 | engines: 251 | node: '>=0.10.0' 252 | resolution: 253 | integrity: sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U= 254 | /find-up/4.1.0: 255 | dependencies: 256 | locate-path: 5.0.0 257 | path-exists: 4.0.0 258 | dev: true 259 | engines: 260 | node: '>=8' 261 | resolution: 262 | integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== 263 | /fs-extra/8.1.0: 264 | dependencies: 265 | graceful-fs: 4.2.4 266 | jsonfile: 4.0.0 267 | universalify: 0.1.2 268 | dev: true 269 | engines: 270 | node: '>=6 <7 || >=8' 271 | resolution: 272 | integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== 273 | /fs-tree-utils/0.1.8: 274 | dependencies: 275 | '@tsfun/array': 0.0.0 276 | '@types/fs-extra': 8.1.1 277 | '@types/node': 13.13.32 278 | fs-extra: 8.1.0 279 | monorepo-shared-assets: 0.0.19 280 | tslib: 1.14.1 281 | dev: true 282 | engines: 283 | node: '>= 8.9.0' 284 | resolution: 285 | integrity: sha512-iovSWg4Ch1w7TTlgD0llxrOhPo3xnVks54HnUSXHOCL7Tm1JakcoxKAb5gJVSp5q/1ag7lKcQkf+DAWdBb0tUg== 286 | /fs.realpath/1.0.0: 287 | dev: true 288 | resolution: 289 | integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 290 | /function-bind/1.1.1: 291 | dev: true 292 | resolution: 293 | integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 294 | /get-caller-file/2.0.5: 295 | dev: true 296 | engines: 297 | node: 6.* || 8.* || >= 10.* 298 | resolution: 299 | integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 300 | /glob/7.1.6: 301 | dependencies: 302 | fs.realpath: 1.0.0 303 | inflight: 1.0.6 304 | inherits: 2.0.4 305 | minimatch: 3.0.4 306 | once: 1.4.0 307 | path-is-absolute: 1.0.1 308 | dev: true 309 | resolution: 310 | integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 311 | /graceful-fs/4.2.4: 312 | dev: true 313 | resolution: 314 | integrity: sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== 315 | /has-flag/3.0.0: 316 | dev: true 317 | engines: 318 | node: '>=4' 319 | resolution: 320 | integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 321 | /has/1.0.3: 322 | dependencies: 323 | function-bind: 1.1.1 324 | dev: true 325 | engines: 326 | node: '>= 0.4.0' 327 | resolution: 328 | integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 329 | /immutable/4.0.0-rc.12: 330 | dev: true 331 | resolution: 332 | integrity: sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A== 333 | /import-fresh/3.2.2: 334 | dependencies: 335 | parent-module: 1.0.1 336 | resolve-from: 4.0.0 337 | dev: true 338 | engines: 339 | node: '>=6' 340 | resolution: 341 | integrity: sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw== 342 | /inflight/1.0.6: 343 | dependencies: 344 | once: 1.4.0 345 | wrappy: 1.0.2 346 | dev: true 347 | resolution: 348 | integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 349 | /inherits/2.0.4: 350 | dev: true 351 | resolution: 352 | integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 353 | /is-arrayish/0.2.1: 354 | dev: true 355 | resolution: 356 | integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 357 | /is-core-module/2.1.0: 358 | dependencies: 359 | has: 1.0.3 360 | dev: true 361 | resolution: 362 | integrity: sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA== 363 | /is-fullwidth-code-point/3.0.0: 364 | dev: true 365 | engines: 366 | node: '>=8' 367 | resolution: 368 | integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 369 | /isarray/0.0.1: 370 | dev: true 371 | resolution: 372 | integrity: sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= 373 | /js-tokens/4.0.0: 374 | dev: true 375 | resolution: 376 | integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 377 | /js-yaml/3.14.0: 378 | dependencies: 379 | argparse: 1.0.10 380 | esprima: 4.0.1 381 | dev: true 382 | hasBin: true 383 | resolution: 384 | integrity: sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== 385 | /json-parse-even-better-errors/2.3.1: 386 | dev: true 387 | resolution: 388 | integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== 389 | /jsonfile/4.0.0: 390 | dev: true 391 | optionalDependencies: 392 | graceful-fs: 4.2.4 393 | resolution: 394 | integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 395 | /lines-and-columns/1.1.6: 396 | dev: true 397 | resolution: 398 | integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= 399 | /locate-path/5.0.0: 400 | dependencies: 401 | p-locate: 4.1.0 402 | dev: true 403 | engines: 404 | node: '>=8' 405 | resolution: 406 | integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== 407 | /lookpath/1.1.0: 408 | dev: true 409 | engines: 410 | npm: '>=6.13.4' 411 | hasBin: true 412 | resolution: 413 | integrity: sha512-B9NM7XpVfkyWqfOBI/UW0kVhGw7pJztsduch+1wkbYDi90mYK6/InFul3lG0hYko/VEcVMARVBJ5daFRc5aKCw== 414 | /minimatch/3.0.4: 415 | dependencies: 416 | brace-expansion: 1.1.11 417 | dev: true 418 | resolution: 419 | integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 420 | /minimist/1.2.5: 421 | dev: true 422 | resolution: 423 | integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 424 | /mkdirp/0.5.5: 425 | dependencies: 426 | minimist: 1.2.5 427 | dev: true 428 | hasBin: true 429 | resolution: 430 | integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 431 | /monorepo-shared-assets/0.0.19: 432 | dependencies: 433 | '@tsfun/array': 0.0.0 434 | '@types/node': 13.13.32 435 | immutable: 4.0.0-rc.12 436 | tslib: 1.14.1 437 | dev: true 438 | engines: 439 | node: '>= 8.9.0' 440 | resolution: 441 | integrity: sha512-xUb+p+UnAiR5Zg34IYv8bO0FlFu84xkBJcZXHLLK5DNQS29NQwiNT/qcwS95BWgAcOGgD8M8Sqs2qoXvR9s5QQ== 442 | /once/1.4.0: 443 | dependencies: 444 | wrappy: 1.0.2 445 | dev: true 446 | resolution: 447 | integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 448 | /p-limit/2.3.0: 449 | dependencies: 450 | p-try: 2.2.0 451 | dev: true 452 | engines: 453 | node: '>=6' 454 | resolution: 455 | integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== 456 | /p-locate/4.1.0: 457 | dependencies: 458 | p-limit: 2.3.0 459 | dev: true 460 | engines: 461 | node: '>=8' 462 | resolution: 463 | integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== 464 | /p-try/2.2.0: 465 | dev: true 466 | engines: 467 | node: '>=6' 468 | resolution: 469 | integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 470 | /parent-module/1.0.1: 471 | dependencies: 472 | callsites: 3.1.0 473 | dev: true 474 | engines: 475 | node: '>=6' 476 | resolution: 477 | integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 478 | /parse-json/5.1.0: 479 | dependencies: 480 | '@babel/code-frame': 7.10.4 481 | error-ex: 1.3.2 482 | json-parse-even-better-errors: 2.3.1 483 | lines-and-columns: 1.1.6 484 | dev: true 485 | engines: 486 | node: '>=8' 487 | resolution: 488 | integrity: sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== 489 | /path-exists/4.0.0: 490 | dev: true 491 | engines: 492 | node: '>=8' 493 | resolution: 494 | integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 495 | /path-is-absolute/1.0.1: 496 | dev: true 497 | engines: 498 | node: '>=0.10.0' 499 | resolution: 500 | integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 501 | /path-parse/1.0.6: 502 | dev: true 503 | resolution: 504 | integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 505 | /path-type/4.0.0: 506 | dev: true 507 | engines: 508 | node: '>=8' 509 | resolution: 510 | integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 511 | /require-directory/2.1.1: 512 | dev: true 513 | engines: 514 | node: '>=0.10.0' 515 | resolution: 516 | integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 517 | /require-main-filename/2.0.0: 518 | dev: true 519 | resolution: 520 | integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 521 | /resolve-from/4.0.0: 522 | dev: true 523 | engines: 524 | node: '>=4' 525 | resolution: 526 | integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 527 | /resolve/1.19.0: 528 | dependencies: 529 | is-core-module: 2.1.0 530 | path-parse: 1.0.6 531 | dev: true 532 | resolution: 533 | integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== 534 | /semver/5.7.1: 535 | dev: true 536 | hasBin: true 537 | resolution: 538 | integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 539 | /set-blocking/2.0.0: 540 | dev: true 541 | resolution: 542 | integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 543 | /sprintf-js/1.0.3: 544 | dev: true 545 | resolution: 546 | integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 547 | /static-type-assert/4.0.1_typescript@4.2.3: 548 | dependencies: 549 | typescript: 4.2.3 550 | typescript-compare: 0.0.2 551 | dev: true 552 | peerDependencies: 553 | typescript: ~4.0.0 || ^3.0.0 554 | resolution: 555 | integrity: sha512-/1o4BSVuM2L2Nnj3DC9XGvsY0rHLK0u1nNx2RjC45UysMjSPThreUVCorIt0xfiHap7MLE7domgclGhT6FUuhA== 556 | /string-width/4.2.0: 557 | dependencies: 558 | emoji-regex: 8.0.0 559 | is-fullwidth-code-point: 3.0.0 560 | strip-ansi: 6.0.0 561 | dev: true 562 | engines: 563 | node: '>=8' 564 | resolution: 565 | integrity: sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== 566 | /strip-ansi/6.0.0: 567 | dependencies: 568 | ansi-regex: 5.0.0 569 | dev: true 570 | engines: 571 | node: '>=8' 572 | resolution: 573 | integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 574 | /supports-color/5.5.0: 575 | dependencies: 576 | has-flag: 3.0.0 577 | dev: true 578 | engines: 579 | node: '>=4' 580 | resolution: 581 | integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 582 | /toolcheck/0.1.4: 583 | dependencies: 584 | '@types/cosmiconfig': 5.0.3 585 | '@types/node': 12.19.6 586 | cosmiconfig: 6.0.0 587 | lookpath: 1.1.0 588 | dev: true 589 | hasBin: true 590 | requiresBuild: true 591 | resolution: 592 | integrity: sha512-MAZ8TOCRkz2KIWB1UKVj+eETc/emDV/8eXK1P5/UHA5L7LjLhdmEwy2RM0S2P2OzILLfF1exeOzy0eaLmxVJBA== 593 | /tslib/1.14.1: 594 | dev: true 595 | resolution: 596 | integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 597 | /tslib/1.9.0: 598 | dev: true 599 | resolution: 600 | integrity: sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== 601 | /tslint-config-standard/9.0.0_tslint@6.1.3+typescript@4.2.3: 602 | dependencies: 603 | tslint-eslint-rules: 5.4.0_tslint@6.1.3+typescript@4.2.3 604 | dev: true 605 | peerDependencies: 606 | tslint: '*' 607 | typescript: '*' 608 | resolution: 609 | integrity: sha512-CAw9J743RnPMemQV/XQ4YyNreC+A1NItACfkm+cBedrOkz6CQfwlnbKn8anUXBfoa4Zo4tjAhblRbsMNcSLfSw== 610 | /tslint-eslint-rules/5.4.0_tslint@6.1.3+typescript@4.2.3: 611 | dependencies: 612 | doctrine: 0.7.2 613 | tslib: 1.9.0 614 | tslint: 6.1.3_typescript@4.2.3 615 | tsutils: 3.17.1_typescript@4.2.3 616 | typescript: 4.2.3 617 | dev: true 618 | peerDependencies: 619 | tslint: ^5.0.0 620 | typescript: ^2.2.0 || ^3.0.0 621 | resolution: 622 | integrity: sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w== 623 | /tslint/6.1.3_typescript@4.2.3: 624 | dependencies: 625 | '@babel/code-frame': 7.10.4 626 | builtin-modules: 1.1.1 627 | chalk: 2.4.2 628 | commander: 2.20.3 629 | diff: 4.0.2 630 | glob: 7.1.6 631 | js-yaml: 3.14.0 632 | minimatch: 3.0.4 633 | mkdirp: 0.5.5 634 | resolve: 1.19.0 635 | semver: 5.7.1 636 | tslib: 1.14.1 637 | tsutils: 2.29.0_typescript@4.2.3 638 | typescript: 4.2.3 639 | deprecated: TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information. 640 | dev: true 641 | engines: 642 | node: '>=4.8.0' 643 | hasBin: true 644 | peerDependencies: 645 | typescript: '>=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev' 646 | resolution: 647 | integrity: sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== 648 | /tsutils/2.29.0_typescript@4.2.3: 649 | dependencies: 650 | tslib: 1.14.1 651 | typescript: 4.2.3 652 | dev: true 653 | peerDependencies: 654 | typescript: '>=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev' 655 | resolution: 656 | integrity: sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== 657 | /tsutils/3.17.1_typescript@4.2.3: 658 | dependencies: 659 | tslib: 1.9.0 660 | typescript: 4.2.3 661 | dev: true 662 | engines: 663 | node: '>= 6' 664 | peerDependencies: 665 | typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' 666 | resolution: 667 | integrity: sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== 668 | /typescript-compare/0.0.2: 669 | dependencies: 670 | typescript-logic: 0.0.0 671 | resolution: 672 | integrity: sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA== 673 | /typescript-logic/0.0.0: 674 | resolution: 675 | integrity: sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== 676 | /typescript/4.2.3: 677 | dev: true 678 | engines: 679 | node: '>=4.2.0' 680 | hasBin: true 681 | resolution: 682 | integrity: sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== 683 | /universalify/0.1.2: 684 | dev: true 685 | engines: 686 | node: '>= 4.0.0' 687 | resolution: 688 | integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 689 | /which-module/2.0.0: 690 | dev: true 691 | resolution: 692 | integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 693 | /wrap-ansi/6.2.0: 694 | dependencies: 695 | ansi-styles: 4.3.0 696 | string-width: 4.2.0 697 | strip-ansi: 6.0.0 698 | dev: true 699 | engines: 700 | node: '>=8' 701 | resolution: 702 | integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== 703 | /wrappy/1.0.2: 704 | dev: true 705 | resolution: 706 | integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 707 | /y18n/4.0.0: 708 | dev: true 709 | resolution: 710 | integrity: sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 711 | /yaml/1.10.0: 712 | dev: true 713 | engines: 714 | node: '>= 6' 715 | resolution: 716 | integrity: sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== 717 | /yargs-parser/18.1.3: 718 | dependencies: 719 | camelcase: 5.3.1 720 | decamelize: 1.2.0 721 | dev: true 722 | engines: 723 | node: '>=6' 724 | resolution: 725 | integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== 726 | /yargs/15.4.1: 727 | dependencies: 728 | cliui: 6.0.0 729 | decamelize: 1.2.0 730 | find-up: 4.1.0 731 | get-caller-file: 2.0.5 732 | require-directory: 2.1.1 733 | require-main-filename: 2.0.0 734 | set-blocking: 2.0.0 735 | string-width: 4.2.0 736 | which-module: 2.0.0 737 | y18n: 4.0.0 738 | yargs-parser: 18.1.3 739 | dev: true 740 | engines: 741 | node: '>=8' 742 | resolution: 743 | integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== 744 | specifiers: 745 | clean-typescript-build: ^0.1.5 746 | static-type-assert: ^4.0.1 747 | toolcheck: ^0.1.4 748 | tslint: ^6.1.3 749 | tslint-config-standard: ^9.0.0 750 | typescript: ~4.2.0 751 | typescript-compare: ^0.0.2 752 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "pinVersions": false, 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /spec/append.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Append } from '..' 3 | 4 | compare, ['new']>('equal') 5 | compare, ['old', 'new']>('equal') 6 | compare, [0, 1, 2, 'new']>('equal') 7 | -------------------------------------------------------------------------------- /spec/compare-length.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { CompareLength } from '..' 3 | 4 | compare, 'equal'>('equal') 5 | compare, 'shorterLeft'>('equal') 6 | compare, 'shorterRight'>('equal') 7 | compare, 'equal'>('equal') 8 | compare, 'shorterLeft'>('equal') 9 | compare, 'shorterRight'>('equal') 10 | compare, 'equal'>('equal') 11 | compare, 'equal'>('equal') 12 | -------------------------------------------------------------------------------- /spec/concat-multiple.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { ConcatMultiple } from '..' 3 | 4 | compare, []>('equal') 5 | compare, []>('equal') 6 | compare, [0, 1, 2, 3, 4, 5]>('equal') 7 | compare, ['a', 'b', 'A', 'B', 0, 1, true, false]>('equal') 8 | compare, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>('equal') 9 | -------------------------------------------------------------------------------- /spec/concat.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Concat } from '..' 3 | 4 | compare, []>('equal') 5 | compare, [0]>('equal') 6 | compare, ['a']>('equal') 7 | compare, ['a', 0]>('equal') 8 | compare, [0, 1, 2]>('equal') 9 | compare, ['a', 'b', 'c']>('equal') 10 | compare, ['a', 'b', 'c', 0, 1, 2]>('equal') 11 | -------------------------------------------------------------------------------- /spec/drop.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Drop } from '..' 3 | 4 | compare< 5 | Drop<[0, 1, 2, 3, 4], 2>, 6 | [2, 3, 4] 7 | >('equal') 8 | 9 | compare< 10 | Drop<[0, 1, 2, 3, 4, ...number[]], 2>, 11 | [2, 3, 4, ...number[]] 12 | >('equal') 13 | 14 | compare< 15 | Drop<[0, 1, 2, 3, 4], 9>, 16 | [] 17 | >('equal') 18 | 19 | compare< 20 | Drop<[0, 1, 2, 3, 4, ...number[]], 9>, 21 | number[] 22 | >('equal') 23 | 24 | compare< 25 | Drop, 26 | any[] 27 | >('equal') 28 | 29 | compare< 30 | Drop<[], number>, 31 | [] 32 | >('equal') 33 | 34 | compare< 35 | Drop, 36 | any[] 37 | >('equal') 38 | -------------------------------------------------------------------------------- /spec/fill-tuple.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { FillTuple } from '..' 3 | 4 | compare, []>('equal') 5 | compare, ['x', 'x', 'x']>('equal') 6 | compare, 'x'[]>('equal') 7 | compare, 'x'[]>('equal') 8 | -------------------------------------------------------------------------------- /spec/filter.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { FilterTuple } from '..' 3 | 4 | compare, [1]>('equal') 5 | compare, []>('equal') 6 | compare, [1, 1]>('equal') 7 | compare, [1]>('equal') 8 | compare, [null]>('equal') 9 | compare, [1, '1', true]>('equal') 10 | -------------------------------------------------------------------------------- /spec/first.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { First } from '..' 3 | 4 | compare, 'sole'>('equal') 5 | compare, 'first'>('equal') 6 | -------------------------------------------------------------------------------- /spec/is-finite.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { IsFinite } from '..' 3 | 4 | compare, true>('equal') 5 | compare, 'finite'>('equal') 6 | compare, false>('equal') 7 | compare, 'infinite'>('equal') 8 | compare, true>('equal') 9 | compare, 'finite'>('equal') 10 | compare, false>('equal') 11 | compare, 'infinite'>('equal') 12 | -------------------------------------------------------------------------------- /spec/last.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Last } from '..' 3 | 4 | compare, 'last'>('equal') 5 | compare, 'last'>('equal') 6 | compare, 'last'>('equal') 7 | compare, 'last'>('equal') 8 | -------------------------------------------------------------------------------- /spec/longest-tuple.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { LongestTuple } from '..' 3 | 4 | compare, [0, 1, 2, 3]>('equal') 5 | compare, 'x'[]>('equal') 6 | compare, 'x'[]>('equal') 7 | compare, 'x'[]>('equal') 8 | compare, 'x'[]>('equal') 9 | compare, [3, 4, 5]>('equal') 10 | compare, [0, 1, 2]>('equal') 11 | compare, [0, 1, 2, 3, 4, 5]>('equal') 12 | compare, [0, 1, 2, 3]>('equal') 13 | compare, [0, 1, 2, 3]>('equal') 14 | compare, [0, 1, 2, 3]>('equal') 15 | -------------------------------------------------------------------------------- /spec/prepend.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Prepend } from '..' 3 | 4 | compare, ['new']>('equal') 5 | compare, ['new', 'old']>('equal') 6 | compare, ['new', 0, 1, 2]>('equal') 7 | -------------------------------------------------------------------------------- /spec/repeat.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Repeat } from '..' 3 | 4 | compare, []>('equal') 5 | compare, ['x']>('equal') 6 | compare, ['x', 'x', 'x', 'x']>('equal') 7 | compare, 'x'[]>('equal') 8 | compare, [] | ['x']>('equal') 9 | compare, [] | ['x', 'x', 'x']>('equal') 10 | compare, ['x', 'x'] | ['x']>('equal') 11 | compare, ['x', 'x'] | ['x', 'x', 'x']>('equal') 12 | compare, [] | ['x'] | ['x', 'x'] | ['x', 'x', 'x']>('equal') 13 | -------------------------------------------------------------------------------- /spec/reverse.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Reverse } from '..' 3 | 4 | compare, []>('equal') 5 | compare, ['sole']>('equal') 6 | compare, [2, 1, 0]>('equal') 7 | -------------------------------------------------------------------------------- /spec/shortest-tuple.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { ShortestTuple } from '..' 3 | 4 | compare, [0, 1, 2, 3]>('equal') 5 | compare, 'x'[] | any[]>('broaderRight') 6 | compare, []>('equal') 7 | compare, []>('equal') 8 | compare, [true, false]>('equal') 9 | compare, []>('equal') 10 | compare, [true, false]>('equal') 11 | compare, [0]>('equal') 12 | -------------------------------------------------------------------------------- /spec/slice-start-quantity.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { SliceStartQuantity } from '..' 3 | 4 | compare< 5 | SliceStartQuantity<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 4>, 6 | [2, 3, 4, 5] 7 | >('equal') 8 | 9 | compare< 10 | SliceStartQuantity<[0, 1, 2, 3], 2, 4>, 11 | [2, 3] 12 | >('equal') 13 | -------------------------------------------------------------------------------- /spec/sort-two-tuple.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { SortTwoTuple } from '..' 3 | 4 | compare, [['a', 'b'], [0, 1, 2, 3]]>('equal') 5 | compare, 'equal'>('equal') 6 | compare, [[0, 1], ['a', 'b', 'c', 'd']]>('equal') 7 | compare, [[0, 1, 2], ['a', 'b', 'c']]>('equal') 8 | -------------------------------------------------------------------------------- /spec/tail.ts: -------------------------------------------------------------------------------- 1 | import { compare } from 'static-type-assert' 2 | import { Tail } from '..' 3 | 4 | compare, [1, 2, 3]>('equal') 5 | compare, number[]>('equal') 6 | compare, []>('equal') 7 | -------------------------------------------------------------------------------- /spec/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "no-implicit-dependencies": [true, "dev"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "commonjs", 5 | "lib": ["es2017", "es2018", "esnext"], 6 | "declaration": true, 7 | "strict": true, 8 | "moduleResolution": "node", 9 | "esModuleInterop": true, 10 | "pretty": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint-config-standard", 3 | "rules": { 4 | "no-implicit-dependencies": true 5 | } 6 | } 7 | --------------------------------------------------------------------------------