├── .commitlintrc.json ├── .eslintrc.json ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── ---bug-report.md │ └── ---feature-request.md ├── banner.svg ├── blank.png ├── demo.svg ├── logo.png ├── pull_request_template.md └── stale.yml ├── .gitignore ├── .huskyrc.json ├── .travis.yml ├── .versionrc.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── package.json ├── scripts ├── build │ ├── clean.sh │ ├── code.sh │ ├── docs.sh │ └── types.sh ├── ci │ ├── branch │ │ ├── ad.sh │ │ └── bd.sh │ ├── docs │ │ ├── ad.sh │ │ └── bd.sh │ ├── master │ │ ├── ad.sh │ │ └── bd.sh │ └── test │ │ ├── ad.sh │ │ └── bd.sh ├── release.sh ├── test │ ├── all.sh │ ├── code.sh │ ├── lint.sh │ └── types.sh └── tools │ ├── check-deploy.sh │ ├── dt-update-version.ts │ ├── package-test-version.ts │ └── regex-update-file.ts ├── sources ├── Any │ ├── At.ts │ ├── Await.ts │ ├── Cast.ts │ ├── Compute.ts │ ├── Contains.ts │ ├── Equals.ts │ ├── Extends.ts │ ├── If.ts │ ├── Is.ts │ ├── Key.ts │ ├── Keys.ts │ ├── KnownKeys.ts │ ├── Promise.ts │ ├── Try.ts │ ├── Type.ts │ ├── _Internal.ts │ ├── _api.ts │ └── x.ts ├── Boolean │ ├── And.ts │ ├── Not.ts │ ├── Or.ts │ ├── Xor.ts │ ├── _Internal.ts │ └── _api.ts ├── Class │ ├── Class.ts │ ├── Instance.ts │ ├── Parameters.ts │ └── _api.ts ├── Community │ ├── IncludesDeep.ts │ ├── IsLiteral.ts │ └── _api.ts ├── Function │ ├── AutoPath.ts │ ├── Compose.ts │ ├── Compose │ │ ├── List │ │ │ ├── Async.ts │ │ │ └── Sync.ts │ │ └── Multi │ │ │ ├── Async.ts │ │ │ └── Sync.ts │ ├── Curry.ts │ ├── Exact.ts │ ├── Function.ts │ ├── Length.ts │ ├── Narrow.ts │ ├── NoInfer.ts │ ├── Parameters.ts │ ├── Pipe.ts │ ├── Pipe │ │ ├── List │ │ │ ├── Async.ts │ │ │ └── Sync.ts │ │ └── Multi │ │ │ ├── Async.ts │ │ │ └── Sync.ts │ ├── Promisify.ts │ ├── Return.ts │ ├── UnCurry.ts │ ├── ValidPath.ts │ ├── _Internal.ts │ └── _api.ts ├── Iteration │ ├── Iteration.ts │ ├── IterationOf.ts │ ├── Key.ts │ ├── Next.ts │ ├── Pos.ts │ ├── Prev.ts │ ├── _Internal.ts │ └── _api.ts ├── List │ ├── Append.ts │ ├── Assign.ts │ ├── AtLeast.ts │ ├── Compulsory.ts │ ├── CompulsoryKeys.ts │ ├── Concat.ts │ ├── Diff.ts │ ├── Drop.ts │ ├── Either.ts │ ├── Exclude.ts │ ├── ExcludeKeys.ts │ ├── Extract.ts │ ├── Filter.ts │ ├── FilterKeys.ts │ ├── Flatten.ts │ ├── Group.ts │ ├── Has.ts │ ├── HasPath.ts │ ├── Head.ts │ ├── Includes.ts │ ├── Intersect.ts │ ├── IntersectKeys.ts │ ├── KeySet.ts │ ├── Last.ts │ ├── LastKey.ts │ ├── Length.ts │ ├── List.ts │ ├── Longest.ts │ ├── Merge.ts │ ├── MergeAll.ts │ ├── Modify.ts │ ├── NonNullable.ts │ ├── NonNullableKeys.ts │ ├── Nullable.ts │ ├── NullableKeys.ts │ ├── ObjectOf.ts │ ├── Omit.ts │ ├── Optional.ts │ ├── OptionalKeys.ts │ ├── Overwrite.ts │ ├── Partial.ts │ ├── Patch.ts │ ├── PatchAll.ts │ ├── Path.ts │ ├── Paths.ts │ ├── Pick.ts │ ├── Pop.ts │ ├── Prepend.ts │ ├── Readonly.ts │ ├── ReadonlyKeys.ts │ ├── Remove.ts │ ├── Repeat.ts │ ├── Replace.ts │ ├── Required.ts │ ├── RequiredKeys.ts │ ├── Reverse.ts │ ├── Select.ts │ ├── SelectKeys.ts │ ├── Shortest.ts │ ├── Tail.ts │ ├── Take.ts │ ├── UnNest.ts │ ├── Undefinable.ts │ ├── UndefinableKeys.ts │ ├── UnionOf.ts │ ├── Unionize.ts │ ├── Update.ts │ ├── Writable.ts │ ├── WritableKeys.ts │ ├── Zip.ts │ ├── ZipObj.ts │ ├── _Internal.ts │ └── _api.ts ├── Misc │ ├── BuiltIn.ts │ ├── JSON │ │ ├── Array.ts │ │ ├── Object.ts │ │ ├── Primitive.ts │ │ ├── Value.ts │ │ └── _api.ts │ ├── Primitive.ts │ └── _api.ts ├── Number │ ├── Absolute.ts │ ├── Add.ts │ ├── Greater.ts │ ├── GreaterEq.ts │ ├── IsNegative.ts │ ├── IsPositive.ts │ ├── IsZero.ts │ ├── Lower.ts │ ├── LowerEq.ts │ ├── Negate.ts │ ├── Range.ts │ ├── Sub.ts │ └── _api.ts ├── Object │ ├── Assign.ts │ ├── AtLeast.ts │ ├── Compulsory.ts │ ├── CompulsoryKeys.ts │ ├── Diff.ts │ ├── Either.ts │ ├── Exclude.ts │ ├── ExcludeKeys.ts │ ├── Filter.ts │ ├── FilterKeys.ts │ ├── Has.ts │ ├── HasPath.ts │ ├── Includes.ts │ ├── Intersect.ts │ ├── IntersectKeys.ts │ ├── Invert.ts │ ├── ListOf.ts │ ├── Merge.ts │ ├── MergeAll.ts │ ├── Modify.ts │ ├── NonNullable.ts │ ├── NonNullableKeys.ts │ ├── Nullable.ts │ ├── NullableKeys.ts │ ├── Object.ts │ ├── Omit.ts │ ├── Optional.ts │ ├── OptionalKeys.ts │ ├── Overwrite.ts │ ├── P │ │ ├── Merge.ts │ │ ├── Omit.ts │ │ ├── Pick.ts │ │ ├── Readonly.ts │ │ ├── Record.ts │ │ ├── Update.ts │ │ ├── _Internal.ts │ │ └── _api.ts │ ├── Partial.ts │ ├── Patch.ts │ ├── PatchAll.ts │ ├── Path.ts │ ├── Paths.ts │ ├── Pick.ts │ ├── Readonly.ts │ ├── ReadonlyKeys.ts │ ├── Record.ts │ ├── Replace.ts │ ├── Required.ts │ ├── RequiredKeys.ts │ ├── Select.ts │ ├── SelectKeys.ts │ ├── Undefinable.ts │ ├── UndefinableKeys.ts │ ├── UnionOf.ts │ ├── Unionize.ts │ ├── Update.ts │ ├── Writable.ts │ ├── WritableKeys.ts │ ├── _Internal.ts │ └── _api.ts ├── String │ ├── At.ts │ ├── Join.ts │ ├── Length.ts │ ├── Replace.ts │ ├── Split.ts │ ├── _Internal.ts │ └── _api.ts ├── Test.ts ├── Union │ ├── Diff.ts │ ├── Exclude.ts │ ├── Filter.ts │ ├── Has.ts │ ├── Intersect.ts │ ├── IntersectOf.ts │ ├── Last.ts │ ├── ListOf.ts │ ├── Merge.ts │ ├── NonNullable.ts │ ├── Nullable.ts │ ├── Pop.ts │ ├── Replace.ts │ ├── Select.ts │ ├── Strict.ts │ └── _api.ts └── index.ts ├── tests ├── Any.ts ├── Boolean.ts ├── Class.ts ├── Community.ts ├── Function.ts ├── Iteration.ts ├── List.ts ├── Misc.ts ├── Number.ts ├── Object.ts ├── String.ts └── Union.ts └── tsconfig.json /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @millsp -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: millsp 2 | custom: https://www.buymeacoffee.com/millsp 3 | patreon: millsp 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🐞 Bug Report" 3 | about: "Something isn't working well 💔" 4 | 5 | --- 6 | 7 | ## 🐞 Bug Report 8 | 9 | #### Describe the bug 10 | 11 | 12 | #### Reproduce the bug 13 | ```ts 14 | // REPL or a link to your repository if applicable. 15 | // A *self-contained* demonstration of the problem. 16 | ``` 17 | 18 | #### Expected behavior 19 | 20 | 21 | #### Possible Solution 22 | 23 | 24 | #### Screenshots 25 | 26 | 27 | #### Additional context 28 | 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/---feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🍩 Feature Request" 3 | about: "Suggest an idea for this project 💡" 4 | 5 | --- 6 | 7 | ## 🍩 Feature Request 8 | 9 | #### Is your feature request related to a problem? 10 | 11 | 12 | #### Describe the solution you'd like 13 | 14 | 15 | #### Describe alternatives you've considered 16 | 17 | 18 | #### Teachability, Documentation, Adoption, Migration Strategy 19 | 23 | -------------------------------------------------------------------------------- /.github/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/millsp/ts-toolbelt/b8a49285e3ed3a7d8bb8e0b433389eac46a5f140/.github/blank.png -------------------------------------------------------------------------------- /.github/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/millsp/ts-toolbelt/b8a49285e3ed3a7d8bb8e0b433389eac46a5f140/.github/logo.png -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## 🎁 Pull Request 2 | 3 | 4 | * [ ] Used a clear / meaningful title for this pull request 5 | * [ ] Tested the changes in your own code (on your projects) 6 | * [ ] Added / Edited tests to reflect changes (`tests` folder) 7 | * [ ] Have read the **Contributing** part of the **Readme** 8 | * [ ] Passed `npm test` 9 | 10 | 11 | 12 | #### Fixes 13 | 14 | 15 | #### Why have you made changes? 16 | 17 | 18 | #### What changes have you made? 19 | * changed this to achieve this 20 | * changed that to achieve this 21 | * ... 22 | 23 | #### What tests have you updated? 24 | * tested this in `tests/...` 25 | * tested that in `tests/...` 26 | * ... 27 | 28 | #### Is there any breaking changes? 29 | 30 | * [ ] Yes, I changed the public API & documented it 31 | * [ ] Yes, I changed existing tests 32 | * [ ] No, I added to the public API & documented it 33 | * [ ] No, I added to the existing tests 34 | * [ ] I don't know 35 | 36 | #### Anything else worth mentioning? 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned #todo 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | node_modules 3 | .vscode 4 | *.tgz 5 | docs 6 | out 7 | dt -------------------------------------------------------------------------------- /.huskyrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 4 | } 5 | } -------------------------------------------------------------------------------- /.versionrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "types": [ 3 | {"type": "feat", "section": "Features"}, 4 | {"type": "fix", "section": "Bug Fixes"}, 5 | {"type": "build", "section": "Others"}, 6 | {"type": "ci", "section": "Others"}, 7 | {"type": "chore", "section": "Others"}, 8 | {"type": "docs", "section": "Others"}, 9 | {"type": "perf", "section": "Others"}, 10 | {"type": "refactor", "section": "Others"}, 11 | {"type": "revert", "section": "Others"}, 12 | {"type": "style", "section": "Others"}, 13 | {"type": "test", "section": "Others"} 14 | ] 15 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. There are many ways to contribute to the project: 2 | 3 | ### Community 4 | 5 | * [Help the community with answers on Gitter](https://gitter.im/ts-toolbelt/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link) 6 | * [Reporting bugs or requesting new features](https://github.com/millsp/ts-toolbelt/issues/new/choose) 7 | 8 | ### Codebase 9 | 10 | * Improving existing documentation 11 | * Adding new types to the collection 12 | * [Getting involved with things to do](#-whats-next) 13 | 14 | ### Pull Requests 15 | 16 | 1. [Read the tutorial](https://medium.com/free-code-camp/typescript-curry-ramda-types-f747e99744ab) 17 | 18 | 2. Fork the project 19 | 20 | 3. Clone your fork 21 | 22 | 4. Create a pr/**feature** branch 23 | 24 | ```sh 25 | git checkout -b pr/CoolFeature 26 | ``` 27 | 28 | 5. Commit your changes 29 | 30 | You **must** follow the [conventional commit](https://conventionalcommits.org) to be able to commit 31 | ```sh 32 | git commit -m "feat(name): Added this CoolFeature" 33 | ``` 34 | 35 | 6. [Run the tests](#-running-tests) 36 | 37 | 7. Push your changes 38 | 39 | ```sh 40 | npm run release -- --no-tags 41 | ``` 42 | 43 | 8. Open a pull request 44 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | If you have discovered a security vulnerability, please report it via [Tidelift](https://tidelift.com/security). 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-toolbelt", 3 | "version": "9.6.0", 4 | "description": "TypeScript's largest utility library", 5 | "keywords": [ 6 | "safe", 7 | "tools", 8 | "types", 9 | "typesafe", 10 | "typescript" 11 | ], 12 | "homepage": "https://github.com/millsp/ts-toolbelt", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/millsp/ts-toolbelt" 16 | }, 17 | "license": "Apache-2.0", 18 | "author": { 19 | "name": "Pierre-Antoine Mills", 20 | "url": "https://github.com/millsp" 21 | }, 22 | "main": "out/index.js", 23 | "types": "out/index.d.ts", 24 | "files": [ 25 | "out" 26 | ], 27 | "scripts": { 28 | "build:clean": "bash scripts/build/clean.sh", 29 | "build:code": "bash scripts/build/code.sh", 30 | "build:docs": "bash scripts/build/docs.sh", 31 | "build:types": "bash scripts/build/types.sh", 32 | "ci:branch:ad": "bash scripts/ci/branch/ad.sh", 33 | "ci:branch:bd": "bash scripts/ci/branch/bd.sh", 34 | "ci:docs:ad": "bash scripts/ci/docs/ad.sh", 35 | "ci:docs:bd": "bash scripts/ci/docs/bd.sh", 36 | "ci:master:ad": "bash scripts/ci/master/ad.sh", 37 | "ci:master:bd": "bash scripts/ci/master/bd.sh", 38 | "ci:test:ad": "bash scripts/ci/test/ad.sh", 39 | "ci:test:bd": "bash scripts/ci/test/bd.sh", 40 | "release": "bash scripts/release.sh", 41 | "test": "bash scripts/test/all.sh", 42 | "test:code": "bash scripts/test/code.sh", 43 | "test:lint": "bash scripts/test/lint.sh", 44 | "test:types": "bash scripts/test/types.sh" 45 | }, 46 | "dependencies": {}, 47 | "devDependencies": { 48 | "@commitlint/cli": "^11.0.0", 49 | "@commitlint/config-conventional": "^11.0.0", 50 | "@typescript-eslint/parser": "^4.14.0", 51 | "eledoc": "^0.2.0", 52 | "eslint": "^7.18.0", 53 | "eslint-plugin-fp": "^2.3.0", 54 | "eslint-plugin-react": "^7.22.0", 55 | "husky": "^4.3.0", 56 | "npx": "^10.2.0", 57 | "sort-package-json": "^1.48.0", 58 | "standard-version": "^9.1.0", 59 | "ts-node": "^9.1.0", 60 | "tslib": "^2.1.0", 61 | "typedoc": "^0.20.0", 62 | "typescript": "latest" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /scripts/build/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -fr out 4 | rm -fr docs 5 | -------------------------------------------------------------------------------- /scripts/build/code.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p out 4 | 5 | touch out/index.js 6 | -------------------------------------------------------------------------------- /scripts/build/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # creates folder if it doesn't exist yet 4 | mkdir -p docs 5 | 6 | # get the current version of the package 7 | DOCS_VERSION=$(node -p "require('./package.json').version") 8 | 9 | # force typedoc to use higher ts version 10 | rm -rf node_modules/typedoc/node_modules/typescript 11 | # !\ can cause bugs, be vigilent with it 12 | 13 | # generate docs their own version folder 14 | npx typedoc --out "docs/${DOCS_VERSION}" sources --theme node_modules/eledoc/bin/default/ && 15 | 16 | # & for github to display them correctly 17 | touch "docs/${DOCS_VERSION}/.nojekyll" 18 | -------------------------------------------------------------------------------- /scripts/build/types.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p out 4 | 5 | npx tsc sources/index.ts -d --emitDeclarationOnly --outDir out 6 | -------------------------------------------------------------------------------- /scripts/ci/branch/ad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bash ./scripts/tools/check-deploy.sh 4 | -------------------------------------------------------------------------------- /scripts/ci/branch/bd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm run build:clean 4 | npm run build:code && 5 | npm run build:types 6 | -------------------------------------------------------------------------------- /scripts/ci/docs/ad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | -------------------------------------------------------------------------------- /scripts/ci/docs/bd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm run build:clean 4 | 5 | # clone the previous state of the docs 6 | git clone --depth=1 --branch=gh-pages https://github.com/pirix-gh/ts-toolbelt.git docs 7 | 8 | # we only keep the "x.x.x" history docs 9 | cd docs; rm -fr assets modules globals.html index.html; cd .. 10 | 11 | # build the new docs on top of that one 12 | npm run build:docs 13 | 14 | # get the current version of the package 15 | DOCS_VERSION=$(node -p "require('./package.json').version") 16 | 17 | # unpack latest generated docs in root / 18 | rsync -a "${PWD}/docs/${DOCS_VERSION}/" "${PWD}/docs" 19 | -------------------------------------------------------------------------------- /scripts/ci/master/ad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bash ./scripts/tools/check-deploy.sh -------------------------------------------------------------------------------- /scripts/ci/master/bd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm run build:clean 4 | npm run build:code && 5 | npm run build:types 6 | -------------------------------------------------------------------------------- /scripts/ci/test/ad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # rm -fr dt 4 | 5 | # git clone --depth=1 https://github.com/DefinitelyTyped/DefinitelyTyped.git dt && 6 | 7 | # npx ts-node scripts/tools/dt-update-version.ts && 8 | 9 | # cd dt && 10 | 11 | # git commit -am "dependents testing" && 12 | 13 | # npm i && 14 | 15 | # npm test 16 | -------------------------------------------------------------------------------- /scripts/ci/test/bd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm run build:clean 4 | 5 | npx ts-node scripts/tools/package-test-version.ts && 6 | npm run build:code && 7 | npm run build:types -------------------------------------------------------------------------------- /scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Make sure that we passed all tests 4 | npm run test && 5 | 6 | # Get the name of the current branch 7 | BRANCH=`git rev-parse --symbolic-full-name --abbrev-ref HEAD` && 8 | 9 | # Sort package.json, keeps neat 10 | npx sort-package-json && 11 | 12 | # check if we have to do a release 13 | RELEASE=$(node -p "require('./package.json').version.split('.')[2] === '0'") && 14 | 15 | # Publish the current branch origin 16 | if [ "$BRANCH" != "master" ]; then 17 | npx standard-version --skip.tag && # skip changelog 18 | git push origin $BRANCH # not a release 19 | else 20 | if [ "$RELEASE" = "false" ]; then 21 | npx standard-version --skip.tag && # gen changelog 22 | git push origin $BRANCH 23 | else 24 | npx standard-version && # gen changelog 25 | git push origin $BRANCH --follow-tags # only releases 26 | fi; 27 | fi; 28 | -------------------------------------------------------------------------------- /scripts/test/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npm run test:code && 4 | npm run test:lint && 5 | npm run test:types 6 | -------------------------------------------------------------------------------- /scripts/test/code.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | -------------------------------------------------------------------------------- /scripts/test/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npx eslint 'sources/**' 4 | -------------------------------------------------------------------------------- /scripts/test/types.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | npx tsc --noEmit --diagnostics 4 | -------------------------------------------------------------------------------- /scripts/tools/check-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sleep 60s # we'll just wait a little for it to get propagated 4 | 5 | # we replace the travis branch name with "latest" if "master" 6 | PKG_VERSTAG=$(echo ${TRAVIS_BRANCH//master/latest}) 7 | 8 | # we need to compare the current push and published versions 9 | PKG_VERSION=$(node -p "require('./package.json').version") 10 | PUB_VERSION=$(npm info .@${PKG_VERSTAG} version) 11 | 12 | if [ $PKG_VERSION != $PUB_VERSION ]; then 13 | echo 14 | exit 1 # travis has just failed the build, force to fail 15 | fi 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /scripts/tools/dt-update-version.ts: -------------------------------------------------------------------------------- 1 | import replace from './regex-update-file' 2 | 3 | replace('./dt/types', '"ts-toolbelt": ".*"', '"ts-toolbelt": "test"', 4 | [ 5 | '?.*/package.json', 6 | ], 7 | [], 8 | ) 9 | -------------------------------------------------------------------------------- /scripts/tools/package-test-version.ts: -------------------------------------------------------------------------------- 1 | import replace from './regex-update-file' 2 | 3 | replace('.', '"version": "(?.*)"', `"version": "-test.${Date.now()}"`, 4 | [ 5 | 'package.json', 6 | ], 7 | [], 8 | ) 9 | -------------------------------------------------------------------------------- /sources/Any/At.ts: -------------------------------------------------------------------------------- 1 | import {Key} from './Key' 2 | import {List} from '../List/List' 3 | 4 | /** 5 | * Get in `O` the type of a field of key `K` 6 | * @param O to extract from 7 | * @param K to extract at 8 | * @returns [[Any]] 9 | * @example 10 | * ```ts 11 | * import {O} from 'ts-toolbelt' 12 | * 13 | * type User = { 14 | * info: { 15 | * name: string 16 | * age: number 17 | * payment: {} 18 | * } 19 | * id: number 20 | * } 21 | * 22 | * type test0 = O.At // number 23 | * ``` 24 | */ 25 | export type At = 26 | A extends List 27 | ? number extends A['length'] 28 | ? K extends number | `${number}` 29 | ? A[never] | undefined 30 | : undefined 31 | : K extends keyof A ? A[K] : undefined 32 | : unknown extends A ? unknown : 33 | K extends keyof A ? A[K] : 34 | undefined; 35 | -------------------------------------------------------------------------------- /sources/Any/Await.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the result type of a `Promise` 3 | * @param P A promise 4 | * @returns [[Any]] 5 | * @example 6 | * ```ts 7 | * import {C} from 'ts-toolbelt' 8 | * 9 | * const promise = new Promise((res, rej) => res('x')) 10 | * 11 | * type test0 = C.Await // string 12 | * type test1 = C.Await> // number 13 | * ``` 14 | */ 15 | export type Await

= 16 | P extends Promise 17 | ? A 18 | : P 19 | -------------------------------------------------------------------------------- /sources/Any/Cast.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Ask TS to re-check that `A1` extends `A2`. 3 | * And if it fails, `A2` will be enforced anyway. 4 | * Can also be used to add constraints on parameters. 5 | * @param A1 to check against 6 | * @param A2 to cast to 7 | * @returns `A1 | A2` 8 | * @example 9 | * ```ts 10 | * import {A} from 'ts-toolbelt' 11 | * 12 | * type test0 = A.Cast<'42', string> // '42' 13 | * type test1 = A.Cast<'42', number> // number 14 | * ``` 15 | */ 16 | export type Cast = 17 | A1 extends A2 18 | ? A1 19 | : A2 20 | -------------------------------------------------------------------------------- /sources/Any/Compute.ts: -------------------------------------------------------------------------------- 1 | import {Depth} from '../Object/_Internal' 2 | import {BuiltIn} from '../Misc/BuiltIn' 3 | import {Has} from '../Union/Has' 4 | import {If} from './If' 5 | import {Key} from './Key' 6 | 7 | /** 8 | * @hidden 9 | */ 10 | export type ComputeRaw = 11 | A extends Function 12 | ? A 13 | : {[K in keyof A]: A[K]} & unknown 14 | 15 | /** 16 | * @hidden 17 | */ 18 | type ComputeFlat = 19 | A extends BuiltIn ? A : 20 | A extends Array 21 | ? A extends Array> 22 | ? Array<{[K in keyof A[number]]: A[number][K]} & unknown> 23 | : A 24 | : A extends ReadonlyArray 25 | ? A extends ReadonlyArray> 26 | ? ReadonlyArray<{[K in keyof A[number]]: A[number][K]} & unknown> 27 | : A 28 | : {[K in keyof A]: A[K]} & unknown; 29 | 30 | /** 31 | * @hidden 32 | */ 33 | type ComputeDeep = 34 | A extends BuiltIn ? A : If, A, ( 35 | A extends Array 36 | ? A extends Array> 37 | ? Array<{[K in keyof A[number]]: ComputeDeep} & unknown> 38 | : A 39 | : A extends ReadonlyArray 40 | ? A extends ReadonlyArray> 41 | ? ReadonlyArray<{[K in keyof A[number]]: ComputeDeep} & unknown> 42 | : A 43 | : {[K in keyof A]: ComputeDeep} & unknown 44 | )>; 45 | 46 | /** 47 | * Force TS to load a type that has not been computed (to resolve composed 48 | * types that TS haven't fully resolved, for display purposes mostly). 49 | * @param A to compute 50 | * @returns `A` 51 | * @example 52 | * ```ts 53 | * import {A} from 'ts-toolbelt' 54 | * 55 | * type test0 = A.Compute<{x: 'x'} & {y: 'y'}> // {x: 'x', y: 'y'} 56 | * ``` 57 | */ 58 | export type Compute = { 59 | 'flat': ComputeFlat 60 | 'deep': ComputeDeep 61 | }[depth] 62 | -------------------------------------------------------------------------------- /sources/Any/Contains.ts: -------------------------------------------------------------------------------- 1 | import {Extends} from './Extends' 2 | 3 | /** 4 | * Check whether `A1` is part of `A2` or not. It works like 5 | * [[Extends]] but [[Boolean]] results are narrowed to [[False]]. 6 | * @param A1 7 | * @param A2 8 | * @returns [[Boolean]] 9 | * @example 10 | * ```ts 11 | * type test0 = A.Contains<'a' | 'b', 'b'> // False 12 | * type test1 = A.Contains<'a', 'a' | 'b'> // True 13 | * 14 | * type test2 = A.Contains<{a: string}, {a: string, b: number}> // False 15 | * type test3 = A.Contains<{a: string, b: number}, {a: string}> // True 16 | * 17 | * type test4 = A.Contains // False 18 | * /// Nothing cannot contain nothing, use `A.Equals` 19 | * ``` 20 | */ 21 | export type Contains = 22 | Extends extends 1 23 | ? 1 24 | : 0 25 | -------------------------------------------------------------------------------- /sources/Any/Equals.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Check whether `A1` is equal to `A2` or not. 3 | * @param A1 4 | * @param A2 5 | * @returns [[Boolean]] 6 | * @example 7 | * ```ts 8 | * import {A} from 'ts-toolbelt' 9 | * 10 | * type test0 = A.Equals<42 | 0, 42 | 0> // true 11 | * type test1 = A.Equals<{a: string}, {b: string}> // false 12 | * type test3 = A.Equals<{a: string}, {readonly a: string}> // false 13 | * ``` 14 | */ 15 | export type Equals = 16 | (() => A extends A2 ? 1 : 0) extends (() => A extends A1 ? 1 : 0) 17 | ? 1 18 | : 0 19 | 20 | // Credit https://stackoverflow.com/a/52473108/3570903 21 | -------------------------------------------------------------------------------- /sources/Any/Extends.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Check whether `A1` is part of `A2` or not. The difference with 3 | * `extends` is that it forces a [[Boolean]] return. 4 | * @param A1 5 | * @param A2 6 | * @returns [[Boolean]] 7 | * @example 8 | * ```ts 9 | * import {A} from 'ts-toolbelt' 10 | * 11 | * type test0 = A.Extends<'a' | 'b', 'b'> // Boolean 12 | * type test1 = A.Extends<'a', 'a' | 'b'> // True 13 | * 14 | * type test2 = A.Extends<{a: string}, {a: any}> // True 15 | * type test3 = A.Extends<{a: any}, {a: any, b: any}> // False 16 | * 17 | * type test4 = A.Extends // False 18 | * /// Nothing cannot extend nothing, use `A.Equals` 19 | * ``` 20 | */ 21 | export type Extends = 22 | [A1] extends [never] 23 | ? 0 24 | : A1 extends A2 25 | ? 1 26 | : 0 27 | 28 | /* 29 | * Comes from the fact that `never` is a fall-through type that we want to 30 | * narrow down to `0`. So it means that `Extends` is false 31 | */ 32 | -------------------------------------------------------------------------------- /sources/Any/If.ts: -------------------------------------------------------------------------------- 1 | import {Boolean} from '../Boolean/_Internal' 2 | 3 | export type If = 4 | B extends 1 5 | ? Then 6 | : Else 7 | -------------------------------------------------------------------------------- /sources/Any/Is.ts: -------------------------------------------------------------------------------- 1 | import {Match} from './_Internal' 2 | import {Extends} from './Extends' 3 | import {Equals} from './Equals' 4 | import {Contains} from './Contains' 5 | 6 | /** 7 | * Check whether `A` is similar to `A1` or not. In other words, it is a compact 8 | * type that bundles [[Equals]], [[Extends]], [[Contains]], comparison types. 9 | * @param A to be compared 10 | * @param A1 to compare to 11 | * @param match (?=`'default'`) to change precision 12 | * @returns [[Boolean]] 13 | * @example 14 | * ```ts 15 | * import {A} from 'ts-toolbelt' 16 | * 17 | * type test0 = A.Is<'a', 'a' | 'b', 'extends->'> // True 18 | * type test1 = A.Is<'a' | 'b', 'a', 'extends->'> // Boolean 19 | * 20 | * type test2 = A.Is<'a', 'a' | 'b', '<-extends'> // Boolean 21 | * type test3 = A.Is<'a' | 'b', 'a', '<-extends'> // True 22 | * 23 | * type test4 = A.Is<'a', 'a' | 'b', 'contains->'> // True 24 | * type test5 = A.Is<'a' | 'b', 'a', 'contains->'> // False 25 | * 26 | * type test6 = A.Is<'a', 'a' | 'b', '<-contains'> // False 27 | * type test7 = A.Is<'a' | 'b', 'a', '<-contains'> // True 28 | * 29 | * type test8 = A.Is<'a', 'a' | 'b', 'equals'> // False 30 | * type test9 = A.Is<'b' |'a', 'a' | 'b', 'equals'> // True 31 | * ``` 32 | */ 33 | export type Is = { 34 | 'default' : Extends 35 | 'contains->': Contains 36 | 'extends->' : Extends 37 | '<-contains': Contains 38 | '<-extends' : Extends 39 | 'equals' : Equals 40 | }[match] 41 | -------------------------------------------------------------------------------- /sources/Any/Key.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Describes index keys for any type 3 | */ 4 | export type Key = string | number | symbol 5 | -------------------------------------------------------------------------------- /sources/Any/Keys.ts: -------------------------------------------------------------------------------- 1 | import {List} from '../List/List' 2 | 3 | /** 4 | * Get the keys of `A` 5 | * @param A 6 | * @returns [[Key]] 7 | * @example 8 | * ```ts 9 | * ``` 10 | */ 11 | export type Keys = 12 | A extends List 13 | ? Exclude | number 14 | : keyof A 15 | -------------------------------------------------------------------------------- /sources/Any/KnownKeys.ts: -------------------------------------------------------------------------------- 1 | import {Keys} from './Keys' 2 | 3 | /** 4 | * Get the known keys of an [[Object]] 5 | * @param O 6 | * @returns [[Key]] 7 | * @example 8 | * ```ts 9 | * ``` 10 | */ 11 | export type KnownKeys = { 12 | [K in keyof O]: 13 | string extends K ? never : 14 | number extends K ? never : 15 | K 16 | } extends { 17 | [K in keyof O]: infer U 18 | } ? U & Keys : never; 19 | -------------------------------------------------------------------------------- /sources/Any/Promise.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Create an asynchronous operation like the original `Promise` type but this 3 | * one prevents promises to be wrapped within more promises (not possible). 4 | * @param A 5 | * @example 6 | * ```ts 7 | * import {A} from 'ts-toolbelt' 8 | * 9 | * type test0 = A.Promise> // Promise 10 | * type test1 = Promise> // Promise> 11 | * ``` 12 | */ 13 | export type Promise = 14 | globalThis.Promise< 15 | A extends globalThis.Promise 16 | ? X 17 | : A 18 | > 19 | -------------------------------------------------------------------------------- /sources/Any/Try.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Similar to [[Cast]] but with a custom fallback `Catch`. If it fails, 3 | * it will enforce `Catch` instead of `A2`. 4 | * @param A1 to check against 5 | * @param A2 to try/test with 6 | * @param Catch to fallback to if the test failed 7 | * @returns `A1 | Catch` 8 | * @example 9 | * ```ts 10 | * import {A} from 'ts-toolbelt' 11 | * 12 | * type test0 = A.Try<'42', string> // '42' 13 | * type test1 = A.Try<'42', number> // never 14 | * type test1 = A.Try<'42', number, 'tried'> // 'tried' 15 | * ``` 16 | */ 17 | export type Try = 18 | A1 extends A2 19 | ? A1 20 | : Catch 21 | -------------------------------------------------------------------------------- /sources/Any/Type.ts: -------------------------------------------------------------------------------- 1 | import {Key} from './Key' 2 | 3 | declare const id: unique symbol 4 | 5 | /** 6 | * Create your own opaque sub-type from a type `A` 7 | * @param A to be personalized 8 | * @param Id to name the sub-type 9 | * @returns A new type `Type` 10 | * @example 11 | * ```ts 12 | * import {A} from 'ts-toolbelt' 13 | * 14 | * type EUR = A.Type 15 | * type USD = A.Type 16 | * 17 | * let eurWallet = 10 as EUR 18 | * let usdWallet = 15 as USD 19 | * 20 | * eurWallet = usdWallet // error 21 | * ``` 22 | */ 23 | export type Type = { 24 | [id]: Id 25 | } & A 26 | -------------------------------------------------------------------------------- /sources/Any/_Internal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Describes the match strategy when matching types 3 | * * `default` : `extends->` 4 | * * `contains->` : X contains Y ([[Contains]]) 5 | * * `extends->` : X extends Y ([[Extends]]) 6 | * * `<-contains` : Y contains X ([[Contains]]) 7 | * * `<-extends` : Y extends X ([[Extends]]) 8 | * * `equals` : X equals Y (([[Equals]])) 9 | */ 10 | export type Match = | 'default' 11 | | 'contains->' 12 | | 'extends->' 13 | | '<-contains' 14 | | '<-extends' 15 | | 'equals' 16 | -------------------------------------------------------------------------------- /sources/Any/_api.ts: -------------------------------------------------------------------------------- 1 | /** @ignore *//** */ 2 | 3 | export {Await} from './Await' 4 | export {At} from './At' 5 | export {Cast} from './Cast' 6 | export {Compute} from './Compute' 7 | export {Contains} from './Contains' 8 | export {Equals} from './Equals' 9 | export {Extends} from './Extends' 10 | export {Key} from './Key' 11 | export {Keys} from './Keys' 12 | export {KnownKeys} from './KnownKeys' 13 | export {Is} from './Is' 14 | export {Promise} from './Promise' 15 | export {Try} from './Try' 16 | export {Type} from './Type' 17 | export {x} from './x' 18 | -------------------------------------------------------------------------------- /sources/Any/x.ts: -------------------------------------------------------------------------------- 1 | const _ = Symbol('x') 2 | 3 | /** 4 | * A placeholder that is used in various ways 5 | */ 6 | export type x = typeof _ & {} 7 | -------------------------------------------------------------------------------- /sources/Boolean/And.ts: -------------------------------------------------------------------------------- 1 | import {Boolean} from './_Internal' 2 | 3 | /** 4 | * Logical `&&` operator (behaves like the JS one) 5 | * @param B1 Left-hand side 6 | * @param B2 Right-hand side 7 | * @returns [[Boolean]] 8 | * @example 9 | * ```ts 10 | * import {B} from 'ts-toolbelt' 11 | * 12 | * type test0 = B.And // False 13 | * type test1 = B.And // True 14 | * type test2 = B.And // Boolean 15 | * ``` 16 | */ 17 | export type And = { 18 | 0: { 19 | 0: 0 20 | 1: 0 21 | } 22 | 1: { 23 | 0: 0 24 | 1: 1 25 | } 26 | }[B1][B2] 27 | 28 | -------------------------------------------------------------------------------- /sources/Boolean/Not.ts: -------------------------------------------------------------------------------- 1 | import {Boolean} from './_Internal' 2 | 3 | /** 4 | * Logical `!` operator (behaves like the JS one) 5 | * @param B to negate 6 | * @returns [[Boolean]] 7 | * @example 8 | * ```ts 9 | * import {B} from 'ts-toolbelt' 10 | * 11 | * type test0 = B.Not // False 12 | * type test1 = B.Not // True 13 | * ``` 14 | */ 15 | export type Not = { 16 | 0: 1 17 | 1: 0 18 | }[B] 19 | -------------------------------------------------------------------------------- /sources/Boolean/Or.ts: -------------------------------------------------------------------------------- 1 | import {Boolean} from './_Internal' 2 | 3 | /** 4 | * Logical `||` operator (behaves like the JS one) 5 | * @param B1 Left-hand side 6 | * @param B2 Right-hand side 7 | * @returns [[Boolean]] 8 | * @example 9 | * ```ts 10 | * import {B} from 'ts-toolbelt' 11 | * 12 | * type test0 = B.Or // True 13 | * type test1 = B.Or // True 14 | * type test2 = B.Or // Boolean 15 | * ``` 16 | */ 17 | export type Or = { 18 | 0: { 19 | 0: 0 20 | 1: 1 21 | } 22 | 1: { 23 | 0: 1 24 | 1: 1 25 | } 26 | }[B1][B2] 27 | -------------------------------------------------------------------------------- /sources/Boolean/Xor.ts: -------------------------------------------------------------------------------- 1 | import {Boolean} from './_Internal' 2 | 3 | /** 4 | * Logical `^` operator (behaves like the JS one) 5 | * @param B1 Left-hand side 6 | * @param B2 Right-hand side 7 | * @returns [[Boolean]] 8 | * @example 9 | * ```ts 10 | * import {B} from 'ts-toolbelt' 11 | * 12 | * type test0 = B.Xor // False 13 | * type test1 = B.Xor // True 14 | * type test2 = B.Xor // Boolean 15 | * ``` 16 | */ 17 | export type Xor = { 18 | 0: { 19 | 0: 0 20 | 1: 1 21 | } 22 | 1: { 23 | 0: 1 24 | 1: 0 25 | } 26 | }[B1][B2] 27 | -------------------------------------------------------------------------------- /sources/Boolean/_Internal.ts: -------------------------------------------------------------------------------- 1 | export type Boolean = 0 | 1 2 | -------------------------------------------------------------------------------- /sources/Boolean/_api.ts: -------------------------------------------------------------------------------- 1 | /** @ignore *//** */ 2 | 3 | export {And} from './And' 4 | export {Not} from './Not' 5 | export {Or} from './Or' 6 | export {Xor} from './Xor' 7 | -------------------------------------------------------------------------------- /sources/Class/Class.ts: -------------------------------------------------------------------------------- 1 | import {List} from '../List/List' 2 | 3 | /** 4 | * Alias to create/describe a `class` 5 | * @param P its constructor parameters 6 | * @param R the object it constructs 7 | * @returns `class` 8 | * @example 9 | * ```ts 10 | * import {C} from 'ts-toolbelt' 11 | * 12 | * type test0 = C.Class<[string, number], {a: string, b: number}> 13 | * 14 | * declare const SomeClass: test0 15 | * 16 | * const obj = new SomeClass('foo', 42) // {a: string, b: number} 17 | * ``` 18 | */ 19 | export type Class

= { 20 | new (...args: P): R 21 | } 22 | -------------------------------------------------------------------------------- /sources/Class/Instance.ts: -------------------------------------------------------------------------------- 1 | import {Class} from './Class' 2 | 3 | /** 4 | * Get the instance type of a `class` from a class object 5 | * @param C * *typeof** class 6 | * @returns [[Object]] 7 | * @example 8 | * ```ts 9 | * import {C} from 'ts-toolbelt' 10 | * 11 | * /// `create` takes an instance constructor and creates an instance of it 12 | * declare function create any)>(c: C): C.InstanceOf 13 | * 14 | * class A {} 15 | * class B {} 16 | * 17 | * let a = create(A) // A 18 | * let b = create(B) // B 19 | * ``` 20 | */ 21 | export type Instance = 22 | C extends Class 23 | ? R 24 | : any 25 | -------------------------------------------------------------------------------- /sources/Class/Parameters.ts: -------------------------------------------------------------------------------- 1 | import {Class} from './Class' 2 | 3 | /** 4 | * Get the parameters of a class constructor 5 | * @param C **typeof** class 6 | * @returns [[List]] 7 | * @example 8 | * ```ts 9 | * import {C} from 'ts-toolbelt' 10 | * 11 | * type User = C.Class<[string, string], {firstname: string, lastname: string}> 12 | * 13 | * type test0 = C.Parameters // [string, string] 14 | * ``` 15 | */ 16 | export type Parameters = 17 | C extends Class 18 | ? P 19 | : never 20 | -------------------------------------------------------------------------------- /sources/Class/_api.ts: -------------------------------------------------------------------------------- 1 | /** @ignore *//** */ 2 | 3 | export {Class} from './Class' 4 | export {Instance} from './Instance' 5 | export {Parameters} from './Parameters' 6 | -------------------------------------------------------------------------------- /sources/Community/IncludesDeep.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {UnionOf} from '../Object/UnionOf' 3 | import {Next} from '../Iteration/Next' 4 | import {Prev} from '../Iteration/Prev' 5 | import {Iteration} from '../Iteration/Iteration' 6 | import {IterationOf} from '../Iteration/IterationOf' 7 | import {Is} from '../Any/Is' 8 | import {Boolean} from '../Boolean/_Internal' 9 | import {Cast} from '../Any/Cast' 10 | import {Pos} from '../Iteration/Pos' 11 | 12 | /** 13 | * @hidden 14 | */ 15 | type _IncludesDeep> = { 16 | 0: _IncludesDeep : O, M, match, limit, Next> 17 | 1: 1 18 | 2: 0 19 | }[ 20 | Pos> extends limit // if we go past the limit 21 | ? 2 // end the loop here 22 | : Is // if 0 => continue, if 1 => end 23 | ] 24 | 25 | /** 26 | * Check whether `O`, or its sub-objects have fields that match `M` 27 | * where the maximum allowed depth is set with `limit`. 28 | * 29 | * @param O to be inspected 30 | * @param M to check field type 31 | * @param match (?=`'default'`) to change precision 32 | * @param limit (?=`'10'`) to change the check depth 33 | * @returns [[Boolean]] 34 | * @example 35 | * ```ts 36 | * ``` 37 | * @author millsp, ctrlplusb 38 | */ 39 | export type IncludesDeep = 40 | _IncludesDeep extends infer X 41 | ? Cast 42 | : never 43 | -------------------------------------------------------------------------------- /sources/Community/IsLiteral.ts: -------------------------------------------------------------------------------- 1 | import {And} from '../Boolean/And' 2 | import {Or} from '../Boolean/Or' 3 | import {Extends} from '../Any/Extends' 4 | 5 | /** 6 | * @hidden 7 | */ 8 | export type IsStringLiteral = 9 | A extends string 10 | ? string extends A 11 | ? 0 12 | : 1 13 | : 0 14 | 15 | /** 16 | * @hidden 17 | */ 18 | export type IsNumberLiteral = 19 | A extends number 20 | ? number extends A 21 | ? 0 22 | : 1 23 | : 0 24 | 25 | /** 26 | * Literal to restrict against 27 | */ 28 | export type Kind = string | number 29 | 30 | /** 31 | * Determine whether `A` is literal or not 32 | * @param A to be checked 33 | * @param kind (?=`'string' | 'number'`) to restrict 34 | * @example 35 | * ```ts 36 | * import {A} from 'ts-toolbelt' 37 | * 38 | * type test0 = A.IsLiteral<1 | 2> // 1 39 | * type test1 = A.IsLiteral<1 | 2, string> // 0 40 | * type test2 = A.IsLiteral<1 | '2', string> // 0 | 1 41 | * type test3 = A.IsLiteral // 0 42 | * ``` 43 | */ 44 | export type IsLiteral = 45 | And, IsNumberLiteral>, Extends> 46 | -------------------------------------------------------------------------------- /sources/Community/_api.ts: -------------------------------------------------------------------------------- 1 | /** @ignore *//** */ 2 | 3 | export {IncludesDeep} from './IncludesDeep' 4 | export {IsLiteral} from './IsLiteral' 5 | -------------------------------------------------------------------------------- /sources/Function/Compose.ts: -------------------------------------------------------------------------------- 1 | import {IntersectOf} from '../Union/IntersectOf' 2 | import {ComposeListAsync} from './Compose/List/Async' 3 | import {ComposeListSync} from './Compose/List/Sync' 4 | import {ComposeMultiAsync} from './Compose/Multi/Async' 5 | import {ComposeMultiSync} from './Compose/Multi/Sync' 6 | import {Input, Mode} from './_Internal' 7 | 8 | /** 9 | * Compose [[Function]]s together 10 | * @param mode (?=`'sync'`) sync/async (this depends on your implementation) 11 | * @param input (?=`'multi'`) whether you want it to take a list or parameters 12 | * @example 13 | * ```ts 14 | * import {F} from 'ts-toolbelt' 15 | * 16 | * /// If you are looking for creating types for `compose` 17 | * /// `Composer` will check for input & `Compose` the output 18 | * declare const compose: F.Compose 19 | * 20 | * const a = (a1: number) => `${a1}` 21 | * const c = (c1: string[]) => [c1] 22 | * const b = (b1: string) => [b1] 23 | * 24 | * compose(c, b, a)(42) 25 | * 26 | * /// And if you are looking for an async `compose` type 27 | * declare const compose: F.Compose<'async'> 28 | * 29 | * const a = async (a1: number) => `${a1}` 30 | * const b = async (b1: string) => [b1] 31 | * const c = async (c1: string[]) => [c1] 32 | * 33 | * await compose(c, b, a)(42) 34 | */ 35 | export type Compose = IntersectOf<{ 36 | 'sync' : { 37 | 'multi': ComposeMultiSync 38 | 'list' : ComposeListSync 39 | } 40 | 'async': { 41 | 'multi': ComposeMultiAsync 42 | 'list' : ComposeListAsync 43 | } 44 | }[mode][input]> // `IntersectOf` in case of unions 45 | -------------------------------------------------------------------------------- /sources/Function/Exact.ts: -------------------------------------------------------------------------------- 1 | import {Narrowable} from './_Internal' 2 | 3 | /** 4 | * Force `A` to comply with `W`. `A` must be a shape of `W`. In other words, `A` 5 | * must extend `W` and have the same properties - no more, no less. 6 | * @param A 7 | * @param W 8 | */ 9 | type Exact = 10 | W extends unknown ? 11 | A extends W 12 | ? A extends Narrowable 13 | ? A 14 | : { 15 | [K in keyof A]: K extends keyof W 16 | ? Exact 17 | : never 18 | } 19 | : W 20 | : never; 21 | 22 | export {Exact} 23 | -------------------------------------------------------------------------------- /sources/Function/Function.ts: -------------------------------------------------------------------------------- 1 | import {List} from '../List/List' 2 | 3 | /** 4 | * Alias to create a [[Function]] 5 | * @param P parameters 6 | * @param R return type 7 | * @returns [[Function]] 8 | * @example 9 | * ```ts 10 | * import {F} from 'ts-toolbelt' 11 | * 12 | * type test0 = F.Function<[string, number], boolean> 13 | * /// (args_0: string, args_1: number) => boolean 14 | * ``` 15 | */ 16 | export type Function

= 17 | (...args: P) => R 18 | -------------------------------------------------------------------------------- /sources/Function/Length.ts: -------------------------------------------------------------------------------- 1 | import {Function} from './Function' 2 | import {Parameters} from './Parameters' 3 | import {Length as LLength} from '../List/Length' 4 | 5 | /** 6 | * Extract arguments' length from a [[Function]] 7 | * @param F to extract from 8 | * @returns [[String]] or `number` 9 | * @example 10 | * ```ts 11 | * import {F} from 'ts-toolbelt' 12 | * 13 | * const fn = (a1: any, a2: any) => {} 14 | * 15 | * type test0 = F.LengthOf // 2 16 | * 17 | * type test1 = F.LengthOf<(a1?: any) => any> // 0 | 1 18 | * 19 | * type test2 = F.LengthOf<(...a: any[]) => any> // number 20 | * ``` 21 | */ 22 | export type Length = 23 | LLength> 24 | -------------------------------------------------------------------------------- /sources/Function/Narrow.ts: -------------------------------------------------------------------------------- 1 | import {Try} from '../Any/Try' 2 | import {Narrowable} from './_Internal' 3 | 4 | /** 5 | * @hidden 6 | */ 7 | type NarrowRaw = 8 | | (A extends [] ? [] : never) 9 | | (A extends Narrowable ? A : never) 10 | | ({[K in keyof A]: A[K] extends Function 11 | ? A[K] 12 | : NarrowRaw}); 13 | 14 | /** 15 | * Prevent type widening on generic function parameters 16 | * @param A to narrow 17 | * @returns `A` 18 | * @example 19 | * ```ts 20 | * import {F} from 'ts-toolbelt' 21 | * 22 | * declare function foo(x: F.Narrow): A; 23 | * declare function bar(x: F.Narrow): A; 24 | * 25 | * const test0 = foo(['e', 2, true, {f: ['g', ['h']]}]) 26 | * // `A` inferred : ['e', 2, true, {f: ['g']}] 27 | * 28 | * const test1 = bar({a: 1, b: 'c', d: ['e', 2, true, {f: ['g']}]}) 29 | * // `A` inferred : {a: 1, b: 'c', d: ['e', 2, true, {f: ['g']}]} 30 | * ``` 31 | */ 32 | type Narrow = 33 | Try> 34 | 35 | export {Narrow} 36 | -------------------------------------------------------------------------------- /sources/Function/NoInfer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Explain to TS which function parameter has priority for generic inference 3 | * @param A to de-prioritize 4 | * @returns `A` 5 | * @example 6 | * ```ts 7 | * import {F} from 'ts-toolbelt' 8 | * 9 | * const fn0 = (a0: A, a1: F.NoInfer): A => { 10 | * return {} as unknown as A // just for the example 11 | * } 12 | * 13 | * const fn1 = (a0: F.NoInfer, a1: A): A => { 14 | * return {} as unknown as A // just for the example 15 | * } 16 | * 17 | * const fn2 = (a0: F.NoInfer, a1: F.NoInfer): A => { 18 | * return {} as unknown as A // just for the example 19 | * } 20 | * 21 | * const test0 = fn0('b', 'a') // error: infer priority is `a0` 22 | * const test1 = fn1('b', 'a') // error: infer priority is `a1` 23 | * const test2 = fn2('b', 'a') // works: infer priority is `a0` | `a1` 24 | * ``` 25 | * @see https://stackoverflow.com/questions/56687668 26 | */ 27 | export type NoInfer = 28 | [A][A extends any ? 0 : never] 29 | 30 | /* 31 | * https://github.com/microsoft/TypeScript/issues/14829#issuecomment-322267089 32 | * https://stackoverflow.com/questions/56687668 33 | */ 34 | 35 | 36 | -------------------------------------------------------------------------------- /sources/Function/Parameters.ts: -------------------------------------------------------------------------------- 1 | import {Function} from './Function' 2 | 3 | /** 4 | * Extract parameters from a [[Function]] 5 | * @param F to extract from 6 | * @returns [[List]] 7 | * @example 8 | * ```ts 9 | * import {F} from 'ts-toolbelt' 10 | * 11 | * const fn = (name: string, age: number) => {} 12 | * 13 | * type test0 = F.ParamsOf // [string, number] 14 | * 15 | * type test1 = F.ParamsOf<(name: string, age: number) => {}> // [string, number] 16 | * ``` 17 | */ 18 | export type Parameters = 19 | F extends ((...args: infer L) => any) 20 | ? L 21 | : never 22 | -------------------------------------------------------------------------------- /sources/Function/Pipe.ts: -------------------------------------------------------------------------------- 1 | import {IntersectOf} from '../Union/IntersectOf' 2 | import {PipeListAsync} from './Pipe/List/Async' 3 | import {PipeListSync} from './Pipe/List/Sync' 4 | import {PipeMultiAsync} from './Pipe/Multi/Async' 5 | import {PipeMultiSync} from './Pipe/Multi/Sync' 6 | import {Input, Mode} from './_Internal' 7 | 8 | /** 9 | * Pipe [[Function]]s together 10 | * @param mode (?=`'sync'`) sync/async (this depends on your implementation) 11 | * @param input (?=`'multi'`) whether you want to take a list or multiple parameters 12 | * @returns [[Function]] 13 | * @example 14 | * ```ts 15 | * import {F} from 'ts-toolbelt' 16 | * 17 | * /// If you are looking for creating types for `pipe`: 18 | * declare const pipe: F.Pipe 19 | * 20 | * const a = (a1: number) => `${a1}` 21 | * const b = (b1: string) => [b1] 22 | * const c = (c1: string[]) => [c1] 23 | * 24 | * pipe(a, b, c)(42) 25 | * 26 | * /// And if you are looking for an async `pipe` type: 27 | * declare const pipe: F.Pipe<'async'> 28 | * 29 | * const a = async (a1: number) => `${a1}` 30 | * const b = async (b1: string) => [b1] 31 | * const c = async (c1: string[]) => [c1] 32 | * 33 | * await pipe(a, b, c)(42) 34 | * ``` 35 | */ 36 | export type Pipe = IntersectOf<{ 37 | 'sync' : { 38 | 'multi': PipeMultiSync 39 | 'list' : PipeListSync 40 | } 41 | 'async': { 42 | 'multi': PipeMultiAsync 43 | 'list' : PipeListAsync 44 | } 45 | }[mode][input]> // `IntersectOf` in case of unions 46 | -------------------------------------------------------------------------------- /sources/Function/Promisify.ts: -------------------------------------------------------------------------------- 1 | import {Function} from './Function' 2 | import {Parameters} from './Parameters' 3 | import {Return} from './Return' 4 | import {Promise} from '../Any/Promise' 5 | 6 | /** 7 | * Creates a promisified version of a `Function` `F` 8 | * @param F to promisify 9 | * @returns async F 10 | * @example 11 | * ```ts 12 | * import {F} from 'ts-toolbelt' 13 | * 14 | * type test0 = F.Promisify<(a: number) => number> // (a: number) => Promise 15 | * ``` 16 | */ 17 | export type Promisify = 18 | (...args: Parameters) => Promise> 19 | -------------------------------------------------------------------------------- /sources/Function/Return.ts: -------------------------------------------------------------------------------- 1 | import {Function} from './Function' 2 | import {List} from '../List/List' 3 | 4 | /** 5 | * Extract the return type of a [[Function]] 6 | * @param F to extract from 7 | * @returns [[Any]] 8 | * @example 9 | * ```ts 10 | * import {F} from 'ts-toolbelt' 11 | * 12 | * const fn = () => true 13 | * 14 | * type test0 = F.ReturnOf // boolean 15 | * 16 | * type test1 = F.ReturnOf<() => true> // true 17 | * ``` 18 | */ 19 | export type Return = 20 | F extends ((...args: List) => infer R) 21 | ? R 22 | : never 23 | -------------------------------------------------------------------------------- /sources/Function/UnCurry.ts: -------------------------------------------------------------------------------- 1 | import {Curry} from './Curry' 2 | 3 | /** 4 | * Undoes the work that was done by [[Curry]] 5 | * @param F to uncurry 6 | * @returns [[Function]] 7 | * @example 8 | * ```ts 9 | * import {F} from 'ts-toolbelt' 10 | * 11 | * type test0 = F.Curry<(a: string, b: number) => boolean> 12 | * declare const foo: test0 13 | * const res0 = foo('a') // F.Curry<(b: number) => boolean> & ((b: number) => boolean) 14 | * 15 | * type test1 = F.UnCurry // (a: string, b: number) => boolean 16 | * declare const bar: test1 17 | * const res1 = bar('a') // TS2554: Expected 2 arguments, but got 1. 18 | * ``` 19 | * @ignore 20 | */ 21 | export type UnCurry> = 22 | F extends Curry 23 | ? UF 24 | : never 25 | -------------------------------------------------------------------------------- /sources/Function/_Internal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Describes function modes 3 | * `sync` : Normal function 4 | * `async`: Promised result 5 | */ 6 | export type Mode = 'sync' | 'async' 7 | 8 | /** 9 | * Describes function parameter input 10 | * `multi`: ( a, b, c ... n ) => X 11 | * `list` : ([a, b, c ... n]) => X 12 | */ 13 | export type Input = 'multi' | 'list' 14 | 15 | /** 16 | * Describes types that can be narrowed 17 | */ 18 | export type Narrowable = 19 | | string 20 | | number 21 | | bigint 22 | | boolean 23 | -------------------------------------------------------------------------------- /sources/Function/_api.ts: -------------------------------------------------------------------------------- 1 | /** @ignore *//** */ 2 | 3 | export {AutoPath} from './AutoPath' 4 | export {Compose} from './Compose' 5 | export {Exact} from './Exact' 6 | export {Curry} from './Curry' 7 | export {Function} from './Function' 8 | export {Narrow} from './Narrow' 9 | export {Length} from './Length' 10 | export {NoInfer} from './NoInfer' 11 | export {Parameters} from './Parameters' 12 | export {Pipe} from './Pipe' 13 | export {Promisify} from './Promisify' 14 | export {Return} from './Return' 15 | export {UnCurry} from './UnCurry' 16 | export {ValidPath} from './ValidPath' 17 | -------------------------------------------------------------------------------- /sources/Iteration/IterationOf.ts: -------------------------------------------------------------------------------- 1 | import {IterationMap} from './Iteration' 2 | 3 | /** 4 | * Transform a number into an [[Iteration]] 5 | * (to use [[Prev]], [[Next]], & [[Pos]]) 6 | * @param N to transform 7 | * @returns [[Iteration]] 8 | * @example 9 | * ```ts 10 | * import {I} from 'ts-toolbelt' 11 | * 12 | * type i = I.IterationOf<0> // ["-1", "1", "0", 0, "0"] 13 | * 14 | * type next = I.Next // ["0", "2", "1", 1, "+"] 15 | * type prev = I.Prev // ["-2", "0", "-1", -1, "-"] 16 | * 17 | * type nnext = I.Pos // +1 18 | * type nprev = I.Pos // -1 19 | * ``` 20 | */ 21 | export type IterationOf = 22 | `${N}` extends keyof IterationMap 23 | ? IterationMap[`${N}`] 24 | : IterationMap['__'] 25 | -------------------------------------------------------------------------------- /sources/Iteration/Key.ts: -------------------------------------------------------------------------------- 1 | import {Iteration} from './Iteration' 2 | 3 | /** 4 | * Get the position of `I` (**string**) 5 | * @param I to query 6 | * @returns [[String]] 7 | * @example 8 | * ```ts 9 | * import {I} from 'ts-toolbelt' 10 | * 11 | * type i = I.IterationOf<'20'> 12 | * 13 | * type test0 = I.Key // '20' 14 | * type test1 = I.Key> // '21' 15 | * ``` 16 | */ 17 | export type Key = 18 | `${I[0]}` 19 | -------------------------------------------------------------------------------- /sources/Iteration/Next.ts: -------------------------------------------------------------------------------- 1 | import {Iteration, IterationMap} from './Iteration' 2 | 3 | /** 4 | * Move `I`'s position forward 5 | * @param I to move 6 | * @returns [[Iteration]] 7 | * @example 8 | * ```ts 9 | * import {I} from 'ts-toolbelt' 10 | * 11 | * type i = I.IterationOf<'20'> 12 | * 13 | * type test0 = I.Pos // 20 14 | * type test1 = I.Pos> // 21 15 | * ``` 16 | */ 17 | export type Next = 18 | IterationMap[I[3]] 19 | -------------------------------------------------------------------------------- /sources/Iteration/Pos.ts: -------------------------------------------------------------------------------- 1 | import {Iteration} from './Iteration' 2 | 3 | /** 4 | * Get the position of `I` (**number**) 5 | * @param I to query 6 | * @returns `number` 7 | * @example 8 | * ```ts 9 | * import {I} from 'ts-toolbelt' 10 | * 11 | * type i = I.IterationOf<'20'> 12 | * 13 | * type test0 = I.Pos // 20 14 | * type test1 = I.Pos> // 21 15 | * ``` 16 | */ 17 | export type Pos = 18 | I[0] 19 | -------------------------------------------------------------------------------- /sources/Iteration/Prev.ts: -------------------------------------------------------------------------------- 1 | 2 | import {Iteration, IterationMap} from './Iteration' 3 | /** 4 | * Move `I`'s position backwards 5 | * @param I to move 6 | * @returns [[Iteration]] 7 | * @example 8 | * ```ts 9 | * import {I} from 'ts-toolbelt' 10 | * 11 | * type i = I.IterationOf<'20'> 12 | * 13 | * type test0 = I.Pos // 20 14 | * type test1 = I.Pos> // 19 15 | * ``` 16 | */ 17 | export type Prev = 18 | IterationMap[I[2]] // continues iterating 19 | -------------------------------------------------------------------------------- /sources/Iteration/_Internal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Describes how to perform iterations 3 | */ 4 | export type Way = '->' | '<-' 5 | 6 | // --------------------------------------------------------------------------------------- 7 | 8 | /** 9 | * Generate the [[IterationOf]] type 10 | * @param min -40 11 | * @param max +40 12 | */ 13 | const IterationOfGenerator = (min: number, max: number) => { 14 | // eslint-disable-next-line no-nested-ternary 15 | const sign = (i: number) => `"${i > 0 ? '+' : i < 0 ? '-' : '0'}"` 16 | const prev = (i: number) => `"${i === min ? '__' : i - 1}"` 17 | const next = (i: number) => `"${i === max ? '__' : i + 1}"` 18 | const oppo = (i: number) => `"${i * -1}"` 19 | const entry = (i: number) => `"${i}": [${i}, ${sign(i)}, ${prev(i)}, ${next(i)}, ${oppo(i)}],` 20 | 21 | console.log(`{${entry(min)}`) 22 | 23 | for (let i = min + 1, k = 1; i <= max - 1; i++, k++) 24 | console.log(entry(i)) 25 | 26 | console.log(`${entry(max)}}`) 27 | } 28 | 29 | IterationOfGenerator(-100, +100) 30 | -------------------------------------------------------------------------------- /sources/Iteration/_api.ts: -------------------------------------------------------------------------------- 1 | /** @ignore *//** */ 2 | 3 | export {Iteration} from './Iteration' 4 | export {IterationOf} from './IterationOf' 5 | export {Key} from './Key' 6 | export {Next} from './Next' 7 | export {Pos} from './Pos' 8 | export {Prev} from './Prev' 9 | -------------------------------------------------------------------------------- /sources/List/Append.ts: -------------------------------------------------------------------------------- 1 | import {List} from './List' 2 | 3 | /** 4 | * Add an element `A` at the end of `L`. 5 | * @param L to append to 6 | * @param A to be added to 7 | * @returns [[List]] 8 | * @example 9 | * ```ts 10 | * import {L} from 'ts-toolbelt' 11 | * 12 | * type test0 = L.Append<[1, 2, 3], 4> // [1, 2, 3, 4] 13 | * type test1 = L.Append<[], 'a'> // ['a'] 14 | * type test2 = L.Append // ['a', 'b', 'c'] 15 | * type test3 = L.Append<[1, 2], [3, 4]> // [1, 2, [3, 4]] 16 | * ``` 17 | */ 18 | export type Append = 19 | [...L, A] 20 | -------------------------------------------------------------------------------- /sources/List/Assign.ts: -------------------------------------------------------------------------------- 1 | import {Assign as OAssign} from '../Object/Assign' 2 | import {List} from './List' 3 | import {Depth} from '../Object/_Internal' 4 | import {BuiltIn} from '../Misc/BuiltIn' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * Assign a list of [[List]] into `L` with [[Merge]]. Merges from left to 9 | * right, first items get overridden by the next ones (last-in overrides). 10 | * @param L to assign to 11 | * @param Ls to assign 12 | * @param depth (?=`'flat'`) 'deep' to do it deeply 13 | * @param ignore (?=`BuiltIn`) types not to merge 14 | * @param fill (?=`undefined`) types of `O` to be replaced with ones of `O1` 15 | * @returns [[Object]] 16 | * @example 17 | * ```ts 18 | * import {L} from 'ts-toolbelt' 19 | * 20 | * type test0 = Assign<[1, 2, 3], [[2, 1]]> // [2, 1, 3] 21 | * type test1 = Assign<[], [[1, 2, 3, 4], [2, 4, 6]]> // [2, 4, 6, 4] 22 | * type test2 = Assign<[0, 0, 0, 0, 0], [[0, 1], [0, 2, 0, 4?]]> // [0, 2, 0, 0 | 4, 0] 23 | * ``` 24 | */ 25 | export type Assign, depth extends Depth = 'flat', ignore extends object = BuiltIn, fill extends any = never> = 26 | Cast, List> 27 | -------------------------------------------------------------------------------- /sources/List/AtLeast.ts: -------------------------------------------------------------------------------- 1 | import {Key} from './_Internal' 2 | import {AtLeast as OAtLeast} from '../Object/AtLeast' 3 | import {ObjectOf} from './ObjectOf' 4 | import {_ListOf} from '../Object/ListOf' 5 | import {List} from './List' 6 | import {Keys} from '../Any/Keys' 7 | 8 | /** 9 | * Make that at least one of the keys `K` are required in `L` at a time. 10 | * @param L to make required 11 | * @param K (?=`keyof L`) to choose fields 12 | * @returns [[List]] [[Union]] 13 | * @example 14 | * ```ts 15 | * import {L} from 'ts-toolbelt' 16 | * 17 | * type test0 = L.AtLeast<[1, 2, 3], 0> // [1, 2 | undefined, 3 | undefined] 18 | * type test1 = L.AtLeast<[1, 2, 3], 0 | 1> // [1, 2 | undefined, 3 | undefined] | [1 | undefined, 2, 3 | undefined] 19 | * type test2 = L.AtLeast<[1, 2, 3]> 20 | * // | [1, 2, 3] 21 | * // | [1, 2 | undefined, 3 | undefined] 22 | * // | [1 | undefined, 2, 3 | undefined] 23 | * // | [1 | undefined, 2 | undefined, 3] 24 | * ``` 25 | */ 26 | export type AtLeast> = 27 | OAtLeast, `${K & number}` | K> extends infer U 28 | ? U extends unknown // we distribute over the union 29 | ? _ListOf // each union member to a list 30 | : never 31 | : never 32 | 33 | declare const sym: unique symbol 34 | -------------------------------------------------------------------------------- /sources/List/Compulsory.ts: -------------------------------------------------------------------------------- 1 | import {Depth} from '../Object/_Internal' 2 | import {CompulsoryPart} from '../Object/Compulsory' 3 | import {List} from './List' 4 | import {_Pick} from '../Object/Pick' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * Make that `L`'s fields cannot be [[Nullable]] or [[Optional]] (it's like 9 | * [[Required]] & [[NonNullable]] at once). 10 | * @param L to make compulsory 11 | * @param depth (?=`'flat'`) 'deep' to do it deeply 12 | * @returns [[List]] 13 | * @example 14 | * ```ts 15 | * * import {L} from 'ts-toolbelt' 16 | * 17 | * type test0 = L.Compulsory<[1, 2, 3?, 4?]> // [1, 2, 3, 4] 18 | * type test1 = L.Compulsory<['a', 'b' | undefined, 'c', 'd', 'e' | null]> // ['a', 'b', 'c', 'd', 'e'] 19 | * ``` 20 | */ 21 | export type Compulsory = 22 | Cast, List> 23 | -------------------------------------------------------------------------------- /sources/List/CompulsoryKeys.ts: -------------------------------------------------------------------------------- 1 | import {CompulsoryKeys as OCompulsoryKeys} from '../Object/CompulsoryKeys' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the keys of `L` that are [[Compulsory]] 7 | * 8 | * (⚠️ needs `--strictNullChecks` enabled) 9 | * @param L 10 | * @returns [[Key]] 11 | * @example 12 | * ```ts 13 | * import {L} from 'ts-toolbelt' 14 | * 15 | * type test0 = L.CompulsoryKeys<[1, 2, 3]> // {0: 1, 1: 2, 2: 3} 16 | * ``` 17 | */ 18 | export type CompulsoryKeys = 19 | OCompulsoryKeys> 20 | -------------------------------------------------------------------------------- /sources/List/Concat.ts: -------------------------------------------------------------------------------- 1 | import {List} from './List' 2 | 3 | /** 4 | * Attach `L1` at the end of `L` 5 | * @param L to concat with 6 | * @param L1 to be attached 7 | * @returns [[List]] 8 | * @example 9 | * ```ts 10 | * import {L} from 'ts-toolbelt' 11 | * 12 | * type test0 = L.Concat<[1, 2], [3, 4]> // [1, 2, 3, 4] 13 | * type test1 = L.Concat<[1, 2], [[3], 4]> // [1, 2, [3], 4] 14 | * type test2 = L.Concat<[1, 2], number[]> // [1, 2, ...number[]] 15 | * type test3 = L.Concat // [1, 2, 3] 16 | * ``` 17 | */ 18 | export type Concat = 19 | [...L, ...L1] 20 | -------------------------------------------------------------------------------- /sources/List/Diff.ts: -------------------------------------------------------------------------------- 1 | import {Diff as ODiff} from '../Object/Diff' 2 | import {ListOf} from '../Object/ListOf' 3 | import {Match} from '../Any/_Internal' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Get a [[List]] that is the difference between `L` & `L1` 9 | * (`L`'s differences have priority over `L1`'s if entries overlap) 10 | * (If `match = 'default'`, no type checks are done) 11 | * @param L to check differences with 12 | * @param L1 to check differences against 13 | * @param match (?=`'default'`) to change precision 14 | * @returns [[List]] 15 | * @example 16 | * ```ts 17 | * ``` 18 | */ 19 | export type Diff = 20 | ListOf, ObjectOf, match>> 21 | -------------------------------------------------------------------------------- /sources/List/Drop.ts: -------------------------------------------------------------------------------- 1 | import {Tail} from './Tail' 2 | import {Cast} from '../Any/Cast' 3 | import {IterationOf} from '../Iteration/IterationOf' 4 | import {Iteration} from '../Iteration/Iteration' 5 | import {Way} from '../Iteration/_Internal' 6 | import {List} from './List' 7 | import {Pos} from '../Iteration/Pos' 8 | import {Prev} from '../Iteration/Prev' 9 | import {Prepend} from './Prepend' 10 | import {Naked} from './_Internal' 11 | import {Extends} from '../Any/Extends' 12 | 13 | /** 14 | * @hidden 15 | */ 16 | type DropForth = { 17 | 0: DropForth, Prev> 18 | 1: L 19 | }[Extends<0, Pos>] 20 | 21 | /** 22 | * @hidden 23 | */ 24 | type DropBack, LN extends List = []> = { 25 | 0: DropBack, Prepend]>> 26 | 1: LN 27 | }[Extends<-1, Pos>] 28 | 29 | /** 30 | * @hidden 31 | */ 32 | type __Drop = { 33 | '->': DropForth 34 | '<-': DropBack 35 | }[way] 36 | 37 | /** 38 | * @hidden 39 | */ 40 | export type _Drop = 41 | __Drop, IterationOf, way> extends infer X 42 | ? Cast 43 | : never 44 | 45 | /** 46 | * Remove `N` entries out of `L` 47 | * @param L to remove from 48 | * @param N to remove out 49 | * @param way (?=`'->'`) from front: '->', from end: '<-' 50 | * @returns [[List]] 51 | * @example 52 | * ```ts 53 | * ``` 54 | */ 55 | export type Drop = 56 | L extends unknown 57 | ? N extends unknown 58 | ? _Drop 59 | : never 60 | : never 61 | -------------------------------------------------------------------------------- /sources/List/Either.ts: -------------------------------------------------------------------------------- 1 | import {Key} from './_Internal' 2 | import {Either as OEither} from '../Object/Either' 3 | import {ObjectOf} from './ObjectOf' 4 | import {_ListOf} from '../Object/ListOf' 5 | import {List} from './List' 6 | import {Boolean} from '../Boolean/_Internal' 7 | 8 | /** 9 | * Split `L` into a [[Union]] with `K` keys in such a way that none of 10 | * the keys are ever present with one another within the different unions. 11 | * @param L to split 12 | * @param K to split with 13 | * @param strict (?=`1`) to force excess property checks https://github.com/microsoft/TypeScript/issues/20863 14 | * @returns [[List]] [[Union]] 15 | * @example 16 | * ```ts 17 | * ``` 18 | */ 19 | export type Either = 20 | OEither, `${K & number}` | K, strict> extends infer OE 21 | ? OE extends unknown 22 | ? _ListOf 23 | : never 24 | : never 25 | -------------------------------------------------------------------------------- /sources/List/Exclude.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {ListOf} from '../Object/ListOf' 3 | import {Exclude as OExclude} from '../Object/Exclude' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Exclude the entries of `L1` out of `L` 9 | * (If `match = 'default'`, no type checks are done) 10 | * @param L to remove from 11 | * @param L1 to remove out 12 | * @param match (?=`'default'`) to change precision 13 | * @returns [[List]] 14 | * @example 15 | * ```ts 16 | * ``` 17 | */ 18 | export type Exclude = 19 | ListOf, ObjectOf, match>> 20 | -------------------------------------------------------------------------------- /sources/List/ExcludeKeys.ts: -------------------------------------------------------------------------------- 1 | import {ExcludeKeys as OExcludeKeys} from '../Object/ExcludeKeys' 2 | import {Match} from '../Any/_Internal' 3 | import {ObjectOf} from './ObjectOf' 4 | import {List} from './List' 5 | 6 | /** 7 | * Exclude the keys of `L1` out of the keys of `L` 8 | * (If `match = 'default'`, no type checks are done) 9 | * @param L to remove the keys from 10 | * @param L1 to remove the keys out 11 | * @param match (?=`'default'`) to change precision 12 | * @returns [[Key]] 13 | * @example 14 | * ```ts 15 | * ``` 16 | */ 17 | export type ExcludeKeys = 18 | OExcludeKeys, ObjectOf, match> 19 | -------------------------------------------------------------------------------- /sources/List/Extract.ts: -------------------------------------------------------------------------------- 1 | import {KeySet} from './KeySet' 2 | import {Pick} from './Pick' 3 | import {List} from './List' 4 | 5 | /** 6 | * Pick a range of entries (portion) from `L` 7 | * @param L to pick from 8 | * @param From to start with 9 | * @param To to end with 10 | * @returns [[List]] 11 | * @example 12 | * ```ts 13 | * ``` 14 | */ 15 | export type Extract = 16 | Pick> 17 | -------------------------------------------------------------------------------- /sources/List/Filter.ts: -------------------------------------------------------------------------------- 1 | import {Filter as OFilter} from '../Object/Filter' 2 | import {ListOf} from '../Object/ListOf' 3 | import {Match} from '../Any/_Internal' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Filter out of `L` the entries that match `M` 9 | * @param L to remove from 10 | * @param M to select entries 11 | * @param match (?=`'default'`) to change precision 12 | * @returns [[List]] 13 | * @example 14 | * ```ts 15 | * ``` 16 | */ 17 | export type Filter = 18 | ListOf, M, match>> 19 | -------------------------------------------------------------------------------- /sources/List/FilterKeys.ts: -------------------------------------------------------------------------------- 1 | import {FilterKeys as OFilterKeys} from '../Object/FilterKeys' 2 | import {Match} from '../Any/_Internal' 3 | import {ObjectOf} from './ObjectOf' 4 | import {List} from './List' 5 | 6 | /** 7 | * Filter out the keys of `L` which entries match `M` 8 | * @param L to remove from 9 | * @param M to select entries 10 | * @param match (?=`'default'`) to change precision 11 | * @returns [[Key]] 12 | * @example 13 | * ```ts 14 | * ``` 15 | */ 16 | export type FilterKeys = 17 | OFilterKeys, M, match> 18 | -------------------------------------------------------------------------------- /sources/List/Flatten.ts: -------------------------------------------------------------------------------- 1 | import {List} from './List' 2 | import {_UnNest} from './UnNest' 3 | import {Cast} from '../Any/Cast' 4 | import {Equals} from '../Any/Equals' 5 | import {Iteration} from '../Iteration/Iteration' 6 | import {IterationOf} from '../Iteration/IterationOf' 7 | import {Extends} from '../Any/Extends' 8 | import {Next} from '../Iteration/Next' 9 | import {Or} from '../Boolean/Or' 10 | import {Boolean} from '../Boolean/_Internal' 11 | 12 | /** 13 | * @hidden 14 | */ 15 | type __Flatten> = { 16 | 0: __Flatten<_UnNest, L, strict, limit, Next> 17 | 1: L 18 | }[Or, Extends>] 19 | 20 | /** 21 | * @hidden 22 | */ 23 | export type _Flatten = 24 | __Flatten> extends infer X 25 | ? Cast 26 | : never 27 | 28 | /** 29 | * Remove all dimensions of `L` (10 max) 30 | * @param L to un-nest 31 | * @param strict (?=`1`) `0` to not preserve tuples 32 | * @param limit (?=`string`) to stop un-nesting at 33 | * @returns [[List]] 34 | * @example 35 | * ```ts 36 | * ``` 37 | */ 38 | export type Flatten = 39 | L extends unknown 40 | ? _Flatten 41 | : never 42 | -------------------------------------------------------------------------------- /sources/List/Group.ts: -------------------------------------------------------------------------------- 1 | import {_Drop} from './Drop' 2 | import {_Take} from './Take' 3 | import {Cast} from '../Any/Cast' 4 | import {Append} from './Append' 5 | import {List} from './List' 6 | import {Extends} from '../Any/Extends' 7 | 8 | /** 9 | * @hidden 10 | */ 11 | type __Group = { 12 | 0: __Group<_Drop, N, Append>> 13 | 1: LN 14 | }[Extends>] 15 | 16 | /** 17 | * @hidden 18 | */ 19 | export type _Group = 20 | __Group extends infer X 21 | ? Cast 22 | : never 23 | 24 | /** 25 | * Split `L` into sub-[[List]]s every `N` 26 | * @param L to group 27 | * @param N to split at 28 | * @returns [[List]] 29 | * @example 30 | * ```ts 31 | * ``` 32 | */ 33 | export type Group = 34 | L extends unknown 35 | ? N extends unknown 36 | ? _Group 37 | : never 38 | : never 39 | -------------------------------------------------------------------------------- /sources/List/Has.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {Has as OHas} from '../Object/Has' 3 | import {Key} from './_Internal' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Check whether `L` has a entry of key `K` that matches `M` 9 | * @param L to be inspected 10 | * @param K to choose entry 11 | * @param M (?=`any`) to check entry type 12 | * @param match (?=`'default'`) to change precision 13 | * @returns [[Boolean]] 14 | * @example 15 | * ```ts 16 | * ``` 17 | */ 18 | export type Has = 19 | OHas, `${K & number}` | K, M, match> 20 | -------------------------------------------------------------------------------- /sources/List/HasPath.ts: -------------------------------------------------------------------------------- 1 | import {HasPath as OHasPath} from '../Object/HasPath' 2 | import {Match} from '../Any/_Internal' 3 | import {Key} from '../Any/Key' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Check whether `L` has nested entries that match `M` 9 | * @param L to be inspected 10 | * @param Path to be followed 11 | * @param M (?=`any`) to check entry type 12 | * @param match (?=`'default'`) to change precision 13 | * @returns [[Boolean]] 14 | * @example 15 | * ```ts 16 | * ``` 17 | */ 18 | export type HasPath, M extends any = any, match extends Match = 'default'> = 19 | OHasPath, Path, M, match> 20 | -------------------------------------------------------------------------------- /sources/List/Head.ts: -------------------------------------------------------------------------------- 1 | import {Length} from './Length' 2 | import {List} from './List' 3 | 4 | /** 5 | * Get the first entry of `L` 6 | * @param L to extract from 7 | * @returns [[Any]] 8 | * @example 9 | * ```ts 10 | * ``` 11 | */ 12 | export type Head = 13 | Length extends 0 14 | ? never 15 | : L[0] 16 | -------------------------------------------------------------------------------- /sources/List/Includes.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {Includes as OIncludes} from '../Object/Includes' 3 | import {ObjectOf} from './ObjectOf' 4 | import {List} from './List' 5 | 6 | /** 7 | * Check whether `L` has entries that match `M` 8 | * @param L to be inspected 9 | * @param M to check entry type 10 | * @param match (?=`'default'`) to change precision 11 | * @returns [[Boolean]] 12 | * @example 13 | * ```ts 14 | * ``` 15 | */ 16 | export type Includes = 17 | OIncludes, M, match> 18 | -------------------------------------------------------------------------------- /sources/List/Intersect.ts: -------------------------------------------------------------------------------- 1 | import {Intersect as OIntersect} from '../Object/Intersect' 2 | import {Match} from '../Any/_Internal' 3 | import {ListOf} from '../Object/ListOf' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Get the intersecting entries of `L` & `L1` 9 | * (If `match = 'default'`, no type checks are done) 10 | * @param L to check similarities with 11 | * @param L1 to check similarities against 12 | * @returns [[List]] 13 | * @example 14 | * ```ts 15 | * ``` 16 | */ 17 | export type Intersect = 18 | ListOf, ObjectOf, match>> 19 | -------------------------------------------------------------------------------- /sources/List/IntersectKeys.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {IntersectKeys as OIntersectKeys} from '../Object/IntersectKeys' 3 | import {ObjectOf} from './ObjectOf' 4 | import {List} from './List' 5 | 6 | /** 7 | * Get the intersecting entries of `L` & `L1` 8 | * (If `match = 'default'`, no type checks are done) 9 | * @param L to check similarities with 10 | * @param L1 to check similarities against 11 | * @returns [[Key]] 12 | * @example 13 | * ```ts 14 | * ``` 15 | */ 16 | export type IntersectKeys = 17 | OIntersectKeys, L1, match> 18 | -------------------------------------------------------------------------------- /sources/List/KeySet.ts: -------------------------------------------------------------------------------- 1 | import {Range} from '../Number/Range' 2 | import {UnionOf} from './UnionOf' 3 | 4 | /** 5 | * Create a set of keys 6 | * @param From to start with 7 | * @param To to end with 8 | * @returns [[Key]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type KeySet = 14 | UnionOf'>> 15 | -------------------------------------------------------------------------------- /sources/List/Last.ts: -------------------------------------------------------------------------------- 1 | import {Tail} from './Tail' 2 | import {Length} from './Length' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the last entry of `L` 7 | * @param L to extract from 8 | * @returns [[Any]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type Last = 14 | L[Length>] 15 | -------------------------------------------------------------------------------- /sources/List/LastKey.ts: -------------------------------------------------------------------------------- 1 | import {Length} from './Length' 2 | import {Tail} from './Tail' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the last index of `L` 7 | * @param L to get from 8 | * @returns `number` 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type LastKey = 14 | Length> 15 | -------------------------------------------------------------------------------- /sources/List/Length.ts: -------------------------------------------------------------------------------- 1 | import {List} from './List' 2 | 3 | /** 4 | * Get the length of `L` 5 | * @param L to get length 6 | * @returns [[String]] or `number` 7 | * @example 8 | * ```ts 9 | * ``` 10 | */ 11 | export type Length = 12 | L['length'] 13 | -------------------------------------------------------------------------------- /sources/List/List.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A [[List]] 3 | * @param A its type 4 | * @returns [[List]] 5 | * @example 6 | * ```ts 7 | * type list0 = [1, 2, 3] 8 | * type list1 = number[] 9 | * ``` 10 | */ 11 | export type List = ReadonlyArray 12 | -------------------------------------------------------------------------------- /sources/List/Longest.ts: -------------------------------------------------------------------------------- 1 | import {Has} from '../Union/Has' 2 | import {List} from './List' 3 | 4 | /** 5 | * Get the longest [[List]] of `L` & `L1` 6 | * (`L` has priority if both lengths are equal) 7 | * @param L to compare length 8 | * @param L1 to compare length 9 | * @returns `L | L1` 10 | * @example 11 | * ```ts 12 | * ``` 13 | */ 14 | export type Longest = 15 | L extends unknown ? L1 extends unknown ? 16 | {0: L1, 1: L}[Has] 17 | : never : never 18 | -------------------------------------------------------------------------------- /sources/List/Merge.ts: -------------------------------------------------------------------------------- 1 | import {Merge as OMerge} from '../Object/Merge' 2 | import {List} from './List' 3 | import {Depth} from '../Object/_Internal' 4 | import {BuiltIn} from '../Misc/BuiltIn' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * Accurately merge the fields of `L` with the ones of `L1`. It is 9 | * equivalent to the spread operator in JavaScript. [[Union]]s and [[Optional]] 10 | * fields will be handled gracefully. 11 | * 12 | * (⚠️ needs `--strictNullChecks` enabled) 13 | * @param L to complete 14 | * @param L1 to copy from 15 | * @param depth (?=`'flat'`) 'deep' to do it deeply 16 | * @param ignore (?=`BuiltIn`) types not to merge 17 | * @param fill (?=`undefined`) types of `O` to be replaced with ones of `O1` 18 | * @returns [[List]] 19 | * @example 20 | * ```ts 21 | * ``` 22 | */ 23 | export type Merge = 24 | Cast, List> 25 | -------------------------------------------------------------------------------- /sources/List/MergeAll.ts: -------------------------------------------------------------------------------- 1 | import {MergeAll as OMergeAll} from '../Object/MergeAll' 2 | import {List} from '../List/List' 3 | import {Depth} from '../Object/_Internal' 4 | import {BuiltIn} from '../Misc/BuiltIn' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * [[Merge]] a list of [[List]]s into `L`. Merges from left to right, first 9 | * items get completed by the next ones (last-in completes). 10 | * @param L to start with 11 | * @param Ls to merge 12 | * @param depth (?=`'flat'`) 'deep' to do it deeply 13 | * @param ignore (?=`BuiltIn`) types not to merge 14 | * @param fill (?=`undefined`) types of `O` to be replaced with ones of `O1` 15 | * @returns [[List]] 16 | * @example 17 | * ```ts 18 | * ``` 19 | */ 20 | export type MergeAll, depth extends Depth = 'flat', ignore extends object = BuiltIn, fill extends any = undefined> = 21 | Cast, List> 22 | -------------------------------------------------------------------------------- /sources/List/Modify.ts: -------------------------------------------------------------------------------- 1 | import {Replace} from '../Union/Replace' 2 | import {x} from '../Any/x' 3 | import {List} from './List' 4 | import {Cast} from '../Any/Cast' 5 | import {At} from '../Any/At' 6 | 7 | /** 8 | * Modify `L` with `LMod` & the [[x]] placeholder 9 | * @param L to copy from 10 | * @param LMod to copy to 11 | * @returns [[List]] 12 | * @example 13 | * ```ts 14 | * ``` 15 | */ 16 | export type Modify = Cast<{ 17 | [K in keyof LMod]: Replace, undefined>> 18 | }, List> 19 | -------------------------------------------------------------------------------- /sources/List/NonNullable.ts: -------------------------------------------------------------------------------- 1 | import {_Pick} from '../Object/Pick' 2 | import {Key} from './_Internal' 3 | import {NonNullable as UNonNullable} from '../Union/NonNullable' 4 | import {Depth} from '../Object/_Internal' 5 | import {BuiltIn} from '../Misc/BuiltIn' 6 | import {Cast} from '../Any/Cast' 7 | import {List} from './List' 8 | 9 | /** 10 | * @hidden 11 | */ 12 | export type NonNullableFlat = { 13 | [P in keyof O]: P extends K 14 | ? UNonNullable 15 | : O[P] 16 | } & {} 17 | 18 | /** 19 | * @hidden 20 | */ 21 | type _NonNullableDeep = { 22 | [K in keyof O]: O[K] extends BuiltIn 23 | ? O[K] 24 | : NonNullableDeep 25 | } 26 | 27 | /** 28 | * @hidden 29 | */ 30 | export type NonNullableDeep = 31 | _NonNullableDeep> 32 | 33 | /** 34 | * @hidden 35 | */ 36 | export type NonNullablePart = { 37 | 'flat': NonNullableFlat 38 | 'deep': NonNullableDeep 39 | }[depth] 40 | 41 | /** 42 | * Make some entries of `L` not nullable (deeply or not) 43 | * @param L to make non nullable 44 | * @param K (?=`Key`) to choose fields 45 | * @param depth (?=`'flat'`) 'deep' to do it deeply 46 | * @returns [[List]] 47 | * @example 48 | * ```ts 49 | * ``` 50 | */ 51 | export type NonNullable = 52 | Cast, List> 53 | -------------------------------------------------------------------------------- /sources/List/NonNullableKeys.ts: -------------------------------------------------------------------------------- 1 | import {NonNullableKeys as ONonNullableKeys} from '../Object/NonNullableKeys' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the keys of `L` that are non-nullable 7 | * @param L 8 | * @returns [[Key]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type NonNullableKeys = 14 | ONonNullableKeys> 15 | -------------------------------------------------------------------------------- /sources/List/Nullable.ts: -------------------------------------------------------------------------------- 1 | import {Key} from './_Internal' 2 | import {List} from './List' 3 | import {Update} from '../Object/Update' 4 | import {x} from '../Any/x' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * Make some entries of `L` nullable (deeply or not) 9 | * @param L to make nullable 10 | * @param K (?=`Key`) to choose fields 11 | * @param depth (?=`'flat'`) 'deep' to do it deeply 12 | * @returns [[List]] 13 | * @example 14 | * ```ts 15 | * ``` 16 | */ 17 | export type Nullable = 18 | Cast, List> 19 | -------------------------------------------------------------------------------- /sources/List/NullableKeys.ts: -------------------------------------------------------------------------------- 1 | import {NullableKeys as ONullableKeys} from '../Object/NullableKeys' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the keys of `L` that are nullable 7 | * @param L 8 | * @returns [[Key]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type NullableKeys = 14 | ONullableKeys> 15 | -------------------------------------------------------------------------------- /sources/List/ObjectOf.ts: -------------------------------------------------------------------------------- 1 | import {_Omit} from '../Object/Omit' 2 | import {_Pick} from '../Object/Pick' 3 | import {Length} from './Length' 4 | import {List} from './List' 5 | 6 | /** 7 | * Transform a [[List]] into an [[Object]] equivalent 8 | * @param L to transform 9 | * @returns [[Object]] 10 | * @example 11 | * ```ts 12 | * ``` 13 | */ 14 | export type ObjectOf = 15 | O extends unknown 16 | ? number extends Length // detect arrays 17 | ? _Pick // preserves arrays 18 | : _Omit // transforms tuples 19 | : never 20 | -------------------------------------------------------------------------------- /sources/List/Omit.ts: -------------------------------------------------------------------------------- 1 | import {_Omit as _OOmit} from '../Object/Omit' 2 | import {_ListOf} from '../Object/ListOf' 3 | import {Key} from './_Internal' 4 | import {List} from './List' 5 | import {ObjectOf} from './ObjectOf' 6 | 7 | /** 8 | * @hidden 9 | */ 10 | export type _Omit = 11 | _ListOf<_OOmit, `${K & number}` | K>> 12 | 13 | /** 14 | * Remove out of `L` the entries of key `K` 15 | * @param L to remove from 16 | * @param K to chose entries 17 | * @returns [[List]] 18 | * @example 19 | * ```ts 20 | * ``` 21 | */ 22 | export type Omit = 23 | L extends unknown 24 | ? _Omit 25 | : never 26 | -------------------------------------------------------------------------------- /sources/List/Optional.ts: -------------------------------------------------------------------------------- 1 | import {Cast} from '../Any/Cast' 2 | import {OptionalPart} from '../Object/Optional' 3 | import {Depth} from '../Object/_Internal' 4 | import {List} from './List' 5 | 6 | /** 7 | * Make `L` optional (deeply or not) 8 | * @param L to make optional 9 | * @param depth (?=`'flat'`) 'deep' to do it deeply 10 | * @returns [[List]] 11 | * @example 12 | * ```ts 13 | * ``` 14 | */ 15 | export type Optional = 16 | Cast, List> 17 | -------------------------------------------------------------------------------- /sources/List/OptionalKeys.ts: -------------------------------------------------------------------------------- 1 | import {OptionalKeys as OOptionalKeys} from '../Object/OptionalKeys' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the keys of `L` that are optional 7 | * @param L 8 | * @returns [[Key]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type OptionalKeys = 14 | OOptionalKeys> 15 | -------------------------------------------------------------------------------- /sources/List/Overwrite.ts: -------------------------------------------------------------------------------- 1 | import {Overwrite as OOverwrite} from '../Object/Overwrite' 2 | import {Cast} from '../Any/Cast' 3 | import {List} from './List' 4 | 5 | /** 6 | * Update the entries of `L` with the ones of `L1` 7 | * @param L to update 8 | * @param L1 to update with 9 | * @returns [[Object]] 10 | * @example 11 | * ```ts 12 | * ``` 13 | */ 14 | export type Overwrite = 15 | Cast, List> 16 | -------------------------------------------------------------------------------- /sources/List/Partial.ts: -------------------------------------------------------------------------------- 1 | import {Partial as OPartial} from '../Object/Partial' 2 | import {Depth} from '../Object/_Internal' 3 | import {Cast} from '../Any/Cast' 4 | import {List} from './List' 5 | 6 | /** 7 | * Make all fields of `O` optional (deeply or not) 8 | * @param L to make optional 9 | * @param depth (?=`'flat'`) 'deep' to do it deeply 10 | * @returns [[List]] 11 | * @example 12 | * ```ts 13 | * import {O} from 'ts-toolbelt' 14 | * 15 | * type L = [1, 2, 3, [4, [5]]] 16 | * 17 | * type test0 = O.Partial 18 | * type test1 = O.Partial 19 | * ``` 20 | */ 21 | export type Partial = 22 | Cast, List> 23 | -------------------------------------------------------------------------------- /sources/List/Patch.ts: -------------------------------------------------------------------------------- 1 | import {Patch as OPatch} from '../Object/Patch' 2 | import {List} from './List' 3 | import {Depth} from '../Object/_Internal' 4 | import {BuiltIn} from '../Misc/BuiltIn' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * Complete the fields of `L` with the ones of `L1`. This is a version of 9 | * [[Merge]] that does NOT handle optional fields, it only completes fields of `O` 10 | * with the ones of `O1` if they don't exist. 11 | * 12 | * (⚠️ needs `--strictNullChecks` enabled) 13 | * @param L to complete 14 | * @param L1 to copy from 15 | * @param depth (?=`'flat'`) 'deep' to do it deeply 16 | * @param ignore (?=`BuiltIn`) types not to merge 17 | * @param fill (?=`never`) types of `O` to be replaced with ones of `O1` 18 | * @returns [[List]] 19 | * @example 20 | * ```ts 21 | * ``` 22 | */ 23 | export type Patch = 24 | Cast, List> 25 | -------------------------------------------------------------------------------- /sources/List/PatchAll.ts: -------------------------------------------------------------------------------- 1 | import {PatchAll as OPatchAll} from '../Object/PatchAll' 2 | import {List} from '../List/List' 3 | import {Depth} from '../Object/_Internal' 4 | import {BuiltIn} from '../Misc/BuiltIn' 5 | import {Cast} from '../Any/Cast' 6 | 7 | /** 8 | * [[Patch]] a list of [[List]]s into `L`. Patches from left to right, first 9 | * items get completed by the next ones (last-in completes). 10 | * @param O to start with 11 | * @param Os to patch 12 | * @param depth (?=`'flat'`) 'deep' to do it deeply 13 | * @param ignore (?=`BuiltIn`) types not to merge 14 | * @param fill (?=`never`) types of `O` to be replaced with ones of `O1` 15 | * @returns [[List]] 16 | * @example 17 | * ```ts 18 | * ``` 19 | */ 20 | export type PatchAll, depth extends Depth = 'flat', ignore extends object = BuiltIn, fill extends any = never> = 21 | Cast, List> 22 | -------------------------------------------------------------------------------- /sources/List/Path.ts: -------------------------------------------------------------------------------- 1 | import {Path as OPath} from '../Object/Path' 2 | import {Key} from '../Any/Key' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get in `L` the type of nested properties 7 | * @param L to be inspected 8 | * @param Path to be followed 9 | * @returns [[Any]] 10 | * @example 11 | * ```ts 12 | * ``` 13 | */ 14 | export type Path> = 15 | OPath 16 | -------------------------------------------------------------------------------- /sources/List/Paths.ts: -------------------------------------------------------------------------------- 1 | import {Paths as OPaths} from '../Object/Paths' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get all the possible paths of `L` 7 | * (⚠️ this won't work with circular-refs) 8 | * @param L to be inspected 9 | * @returns [[String]][] 10 | * @example 11 | * ```ts 12 | * ``` 13 | */ 14 | export type Paths = 15 | OPaths> 16 | -------------------------------------------------------------------------------- /sources/List/Pick.ts: -------------------------------------------------------------------------------- 1 | import {_Pick as _OPick} from '../Object/Pick' 2 | import {_ListOf} from '../Object/ListOf' 3 | import {Key} from './_Internal' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * @hidden 9 | */ 10 | export type _Pick = 11 | _ListOf<_OPick, `${K & number}` | K>> 12 | 13 | /** 14 | * Extract out of `L` the entries of key `K` 15 | * @param L to extract from 16 | * @param K to chose entries 17 | * @returns [[List]] 18 | * @example 19 | * ```ts 20 | * ``` 21 | */ 22 | export type Pick = 23 | L extends unknown 24 | ? _Pick 25 | : never 26 | -------------------------------------------------------------------------------- /sources/List/Pop.ts: -------------------------------------------------------------------------------- 1 | import {_Omit} from './Omit' 2 | import {List} from './List' 3 | 4 | /** 5 | * Remove the last element out of `L` 6 | * @param L to remove from 7 | * @returns [[List]] 8 | * @example 9 | * ```ts 10 | * ``` 11 | */ 12 | export type Pop = 13 | L extends (readonly [...infer LBody, any] | readonly [...infer LBody, any?]) 14 | ? LBody 15 | : L 16 | -------------------------------------------------------------------------------- /sources/List/Prepend.ts: -------------------------------------------------------------------------------- 1 | import {List} from './List' 2 | 3 | /** 4 | * Add an element `A` at the beginning of `L` 5 | * @param L to append to 6 | * @param A to be added to 7 | * @returns [[List]] 8 | * @example 9 | * ```ts 10 | * ``` 11 | */ 12 | export type Prepend = 13 | [A, ...L] 14 | -------------------------------------------------------------------------------- /sources/List/Readonly.ts: -------------------------------------------------------------------------------- 1 | import {Depth} from '../Object/_Internal' 2 | import {ReadonlyPart} from '../Object/Readonly' 3 | import {List} from './List' 4 | import {Cast} from '../Any/Cast' 5 | 6 | /** 7 | * Make `L` readonly (deeply or not) 8 | * @param L to make readonly 9 | * @param depth (?=`'flat'`) 'deep' to do it deeply 10 | * @returns [[List]] 11 | * @example 12 | * ```ts 13 | * ``` 14 | */ 15 | export type Readonly = 16 | Cast, List> 17 | -------------------------------------------------------------------------------- /sources/List/ReadonlyKeys.ts: -------------------------------------------------------------------------------- 1 | import {ReadonlyKeys as OReadonlyKeys} from '../Object/ReadonlyKeys' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the keys of `L` that are readonly 7 | * @param L 8 | * @returns [[Key]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type ReadonlyKeys = 14 | OReadonlyKeys> 15 | -------------------------------------------------------------------------------- /sources/List/Remove.ts: -------------------------------------------------------------------------------- 1 | import {KeySet} from './KeySet' 2 | import {Omit} from './Omit' 3 | import {List} from './List' 4 | 5 | /** 6 | * Remove out of `L` a range of entries 7 | * @param L to remove from 8 | * @param From to start from 9 | * @param To to end with 10 | * @returns [[List]] 11 | * @example 12 | * ```ts 13 | * ``` 14 | */ 15 | export type Remove = 16 | Omit> 17 | -------------------------------------------------------------------------------- /sources/List/Repeat.ts: -------------------------------------------------------------------------------- 1 | import {Next} from '../Iteration/Next' 2 | import {Prepend} from './Prepend' 3 | import {IterationOf} from '../Iteration/IterationOf' 4 | import {Iteration} from '../Iteration/Iteration' 5 | import {Cast} from '../Any/Cast' 6 | import {List} from './List' 7 | import {Extends} from '../Any/Extends' 8 | import {Pos} from '../Iteration/Pos' 9 | 10 | /** 11 | * @hidden 12 | */ 13 | type __Repeat> = { 14 | 0: __Repeat, Next> 15 | 1: L 16 | }[Extends, N>] 17 | 18 | /** 19 | * @hidden 20 | */ 21 | export type _Repeat = 22 | __Repeat extends infer X 23 | ? Cast 24 | : never 25 | 26 | /** 27 | * Fill a [[List]] with `N` times `A` 28 | * @param A to fill with 29 | * @param N to repeat it 30 | * @param L (?=`[]`) to be filled 31 | * @returns [[List]] 32 | * @example 33 | * ```ts 34 | * ``` 35 | */ 36 | export type Repeat = 37 | N extends unknown 38 | ? L extends unknown 39 | ? _Repeat 40 | : never 41 | : never 42 | -------------------------------------------------------------------------------- /sources/List/Replace.ts: -------------------------------------------------------------------------------- 1 | import {Replace as OReplace} from '../Object/Replace' 2 | import {Match} from '../Any/_Internal' 3 | import {Cast} from '../Any/Cast' 4 | import {List} from './List' 5 | 6 | /** 7 | * Update with `A` the entries of `L` that match `M` 8 | * @param O to update 9 | * @param M to select fields 10 | * @param A to update with 11 | * @param match (?=`'default'`) to change precision 12 | * @returns [[List]] 13 | * @example 14 | * ```ts 15 | * ``` 16 | */ 17 | export type Replace = 18 | Cast, List> 19 | -------------------------------------------------------------------------------- /sources/List/Required.ts: -------------------------------------------------------------------------------- 1 | import {Depth} from '../Object/_Internal' 2 | import {RequiredPart} from '../Object/Required' 3 | import {List} from './List' 4 | import {Cast} from '../Any/Cast' 5 | 6 | /** 7 | * Make `L` required (deeply or not) 8 | * @param L to make required 9 | * @param depth (?=`'flat'`) 'deep' to do it deeply 10 | * @returns [[List]] 11 | * @example 12 | * ```ts 13 | * ``` 14 | */ 15 | export type Required = 16 | Cast, List> 17 | -------------------------------------------------------------------------------- /sources/List/RequiredKeys.ts: -------------------------------------------------------------------------------- 1 | import {RequiredKeys as ORequiredKeys} from '../Object/RequiredKeys' 2 | import {ObjectOf} from './ObjectOf' 3 | import {List} from './List' 4 | 5 | /** 6 | * Get the keys of `L` that are readonly 7 | * @param L 8 | * @returns [[Key]] 9 | * @example 10 | * ```ts 11 | * ``` 12 | */ 13 | export type RequiredKeys = 14 | ORequiredKeys> 15 | -------------------------------------------------------------------------------- /sources/List/Reverse.ts: -------------------------------------------------------------------------------- 1 | import {Prepend} from './Prepend' 2 | import {Pos} from '../Iteration/Pos' 3 | import {Next} from '../Iteration/Next' 4 | import {Length} from './Length' 5 | import {IterationOf} from '../Iteration/IterationOf' 6 | import {Iteration} from '../Iteration/Iteration' 7 | import {Cast} from '../Any/Cast' 8 | import {List} from './List' 9 | import {Naked} from './_Internal' 10 | import {Extends} from '../Any/Extends' 11 | 12 | /** 13 | * @hidden 14 | */ 15 | type __Reverse> = { 16 | 0: __Reverse]>, Next> 17 | 1: LO 18 | }[Extends, Length>] 19 | 20 | /** 21 | * @hidden 22 | */ 23 | export type _Reverse = 24 | __Reverse, LO> extends infer X 25 | ? Cast 26 | : never 27 | 28 | /** 29 | * Turn a [[List]] the other way around 30 | * @param L to reverse 31 | * @param LO (?=`[]`) to prepend to 32 | * @returns [[List]] 33 | * @example 34 | * ```ts 35 | * ``` 36 | */ 37 | export type Reverse = 38 | L extends unknown 39 | ? _Reverse 40 | : never 41 | -------------------------------------------------------------------------------- /sources/List/Select.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {Select as OSelect} from '../Object/Select' 3 | import {ListOf} from '../Object/ListOf' 4 | import {ObjectOf} from './ObjectOf' 5 | import {List} from './List' 6 | 7 | /** 8 | * Extract the entries of `L` that match `M` 9 | * @param L to extract from 10 | * @param M to select entries 11 | * @param match (?=`'default'`) to change precision 12 | * @returns [[List]] 13 | * @example 14 | * ```ts 15 | * ``` 16 | */ 17 | export type Select = 18 | ListOf, M, match>> 19 | -------------------------------------------------------------------------------- /sources/List/SelectKeys.ts: -------------------------------------------------------------------------------- 1 | import {Match} from '../Any/_Internal' 2 | import {SelectKeys as OSelectKeys} from '../Object/SelectKeys' 3 | import {ObjectOf} from './ObjectOf' 4 | import {List} from './List' 5 | 6 | /** 7 | * Get the keys of `L` which entries match `M` 8 | * @param L to extract from 9 | * @param M to select entries 10 | * @param match (?=`'default'`) to change precision 11 | * @returns [[Key]] 12 | * @example 13 | * ```ts 14 | * ``` 15 | */ 16 | export type SelectKeys = 17 | OSelectKeys, M, match> 18 | -------------------------------------------------------------------------------- /sources/List/Shortest.ts: -------------------------------------------------------------------------------- 1 | import {Has} from '../Union/Has' 2 | import {List} from './List' 3 | 4 | /** 5 | * Get the shortest [[List]] of `L` & `L1` 6 | * (`L` has priority if both lengths are equal) 7 | * @param L to compare length 8 | * @param L1 to compare length 9 | * @returns `L | L1` 10 | * @example 11 | * ```ts 12 | * ``` 13 | */ 14 | export type Shortest = 15 | L extends unknown ? L1 extends unknown ? 16 | {0: L1, 1: L}[Has] 17 | : never : never 18 | -------------------------------------------------------------------------------- /sources/List/Tail.ts: -------------------------------------------------------------------------------- 1 | import {List} from './List' 2 | 3 | /** 4 | * Remove the first item out of a [[List]] 5 | * @param L 6 | * @returns [[List]] 7 | * @example 8 | * ```ts 9 | * ``` 10 | */ 11 | export type Tail = 12 | L extends readonly [] 13 | ? L 14 | : L extends readonly [any?, ...infer LTail] 15 | ? LTail 16 | : L 17 | -------------------------------------------------------------------------------- /sources/List/Take.ts: -------------------------------------------------------------------------------- 1 | import {IterationOf} from '../Iteration/IterationOf' 2 | import {Iteration} from '../Iteration/Iteration' 3 | import {Pos} from '../Iteration/Pos' 4 | import {Prepend} from './Prepend' 5 | import {Way} from '../Iteration/_Internal' 6 | import {List} from './List' 7 | import {Prev} from '../Iteration/Prev' 8 | import {Cast} from '../Any/Cast' 9 | import {Tail} from './Tail' 10 | import {Extends} from '../Any/Extends' 11 | 12 | /** 13 | * starts in reverse from `N` till `N` = 0 14 | * @hidden 15 | */ 16 | type TakeForth, LN extends List = []> = { 17 | 0: TakeForth, Prepend]>> 18 | 1: LN 19 | }[Extends<-1, Pos>] 20 | 21 | /** 22 | * starts in reverse from the end till `N` = 0 23 | * @hidden 24 | */ 25 | type TakeBack = { 26 | 0: TakeBack, Prev> 27 | 1: L 28 | }[Extends<0, Pos>] 29 | 30 | /** 31 | * @hidden 32 | */ 33 | type __Take = { 34 | '->': TakeForth // Reverse logic to work naturally #`Prepend` 35 | '<-': TakeBack // Reverse logic to work naturally #`Prepend` 36 | }[way] 37 | 38 | /** 39 | * @hidden 40 | */ 41 | export type _Take = 42 | __Take, way> extends infer X 43 | ? Cast 44 | : never 45 | 46 | /** 47 | * Extract `N` entries out of `L` 48 | * @param L to extract from 49 | * @param N to extract out 50 | * @param way (?=`'->'`) to extract from end 51 | * @returns [[List]] 52 | * @example 53 | * ```ts 54 | * ``` 55 | */ 56 | export type Take = 57 | L extends unknown 58 | ? N extends unknown 59 | ? _Take 60 | : never 61 | : never 62 | -------------------------------------------------------------------------------- /sources/List/UnNest.ts: -------------------------------------------------------------------------------- 1 | import {Concat} from './Concat' 2 | import {Append} from './Append' 3 | import {Cast} from '../Any/Cast' 4 | import {Length} from './Length' 5 | import {Iteration} from '../Iteration/Iteration' 6 | import {IterationOf} from '../Iteration/IterationOf' 7 | import {Next} from '../Iteration/Next' 8 | import {Pos} from '../Iteration/Pos' 9 | import {List} from './List' 10 | import {UnionOf} from './UnionOf' 11 | import {Naked} from './_Internal' 12 | import {Extends} from '../Any/Extends' 13 | import {Boolean} from '../Boolean/_Internal' 14 | import {Not} from '../Boolean/Not' 15 | import {And} from '../Boolean/And' 16 | 17 | /** 18 | * @hidden 19 | */ 20 | type UnNestLoose = 21 | (UnionOf extends infer UL // make `L` a union 22 | ? UL extends unknown // for each in union 23 | ? UL extends List // if its an array 24 | ? UnionOf