├── .all-contributorsrc ├── .editorconfig ├── .eslintrc ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── feature_request.md │ └── new_algorithm.yml └── workflows │ └── Ci.yml ├── .gitignore ├── .husky ├── pre-commit └── pre-push ├── .npmignore ├── .npmrc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── docs ├── .nojekyll ├── ArrayUtils │ ├── AsReadOnlyArray.md │ ├── NonEmptyArray.md │ └── UnboxArray.md ├── ClassUtils │ ├── ClassConstructor.md │ ├── ClassInstance.md │ ├── MethodReturnType.md │ └── PublicMethods.md ├── InterfaceUtils │ ├── DeepReadOnly.md │ ├── KeysOfType.md │ ├── OmitByValueType.md │ ├── OverrideInterface.md │ ├── ReadonlyKeys.md │ ├── RequireAtLeastOne.md │ ├── UnionToIntersection.md │ └── WritableKeys.md ├── README.md ├── _coverpage.md ├── _sidebar.md ├── assets │ └── img │ │ ├── LOGO-BANNER.png │ │ ├── LOGO.png │ │ ├── banner.jpg │ │ ├── code.svg │ │ ├── github.svg │ │ └── npm.svg ├── index.html ├── quickstart.md └── robots.txt ├── index.ts ├── jest.config.ts ├── package-lock.json ├── package.json ├── scripts ├── MarkdownGenerateTree.js └── ValidateTest.mjs ├── src ├── ArrayUtils │ ├── AsReadOnlyArray │ │ ├── AsReadOnlyArray.test.ts │ │ └── index.ts │ ├── NonEmptyArray │ │ ├── NonEmptyArray.test.ts │ │ └── index.ts │ ├── UnboxArray │ │ ├── UnboxArray.test.ts │ │ └── index.ts │ └── index.ts ├── ClassUtils │ ├── ClassConstructor │ │ ├── ClassConstructor.test.ts │ │ └── index.ts │ ├── ClassInstance │ │ ├── ClassInstance.test.ts │ │ └── index.ts │ ├── MethodReturnType │ │ ├── MethodReturnType.test.ts │ │ └── index.ts │ ├── PublicMethods │ │ ├── PublicMethods.test.ts │ │ └── index.ts │ └── index.ts └── InterfaceUtils │ ├── DeepReadOnly │ ├── DeepReadOnly.test.ts │ └── index.ts │ ├── KeysOfType │ ├── KeysOfType.test.ts │ └── index.ts │ ├── OmitByValueType │ ├── OmitByValueType.test.ts │ └── index.ts │ ├── OverrideInterface │ ├── OverrideInterface.test.ts │ └── index.ts │ ├── ReadonlyKeys │ ├── ReadonlyKeys.test.ts │ └── index.ts │ ├── RequireAtLeastOne │ ├── RequireAtLeastOne.test.ts │ └── index.ts │ ├── UnionToIntersection │ ├── UnionToIntersection.test.ts │ └── index.ts │ ├── WritableKeys │ ├── WritableKeys.test.ts │ └── index.ts │ └── index.ts ├── test └── utils │ ├── ExampleObjectData.ts │ └── UsuarioClass.ts └── tsconfig.json /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "commitType": "docs", 8 | "commitConvention": "angular", 9 | "contributors": [ 10 | { 11 | "login": "eliseodesign", 12 | "name": "Eliseo F. Arévalo", 13 | "avatar_url": "https://avatars.githubusercontent.com/u/96401071?v=4", 14 | "profile": "https://eliseodesign.github.io/", 15 | "contributions": [ 16 | "doc" 17 | ] 18 | }, 19 | { 20 | "login": "Bryan-Herrera-DEV", 21 | "name": "Bryan Herrera ~ ርᚱ1ናተᛰ ᚻህᚥተპᚱ", 22 | "avatar_url": "https://avatars.githubusercontent.com/u/50712646?v=4", 23 | "profile": "https://bryan-herrera.netlify.app/", 24 | "contributions": [ 25 | "maintenance" 26 | ] 27 | } 28 | ], 29 | "contributorsPerLine": 7, 30 | "skipCi": true, 31 | "repoType": "github", 32 | "repoHost": "https://github.com", 33 | "projectName": "typescript-common-utils", 34 | "projectOwner": "Bryan-Herrera-DEV" 35 | } 36 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended" 11 | ], 12 | "rules": { 13 | "@typescript-eslint/no-inferrable-types": "off", 14 | "quotes": ["error", "double"], 15 | "curly": "error", 16 | "no-empty": "error", 17 | "@typescript-eslint/no-explicit-any": [0, { "ignoreRestArgs": true }], 18 | "@typescript-eslint/no-unused-vars": "error", 19 | "semi": ["error", "always"], 20 | "no-trailing-spaces": ["error", { "ignoreComments": true }], 21 | "keyword-spacing": ["error", { "before": true }], 22 | "space-before-blocks": ["error", "always"], 23 | "space-infix-ops": ["error", { "int32Hint": false }], 24 | "object-curly-spacing": ["error", "always"], 25 | "no-multi-spaces": "error", 26 | "comma-spacing": ["error", { "before": false, "after": true }] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Bryan-Herrera-DEV 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: bryan_herrera_dev 4 | custom: ['https://www.paypal.com/paypalme/bryaneliasherrera'] 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: 'Create a bug report to help us improve our implementations' 3 | title: '[BUG]: ' 4 | labels: ['bug'] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: '### Make sure that your topic is not a duplicate and that you follow our [contribution guidelines](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/blob/main/CONTRIBUTING.md)' 9 | - type: textarea 10 | id: description 11 | attributes: 12 | label: Description 13 | description: Explain what the problem is. 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: expectedbhv 18 | attributes: 19 | label: Expected behavior 20 | description: Describe what was the expected behavior 21 | validations: 22 | required: false 23 | - type: textarea 24 | id: actualbhv 25 | attributes: 26 | label: Current behavior 27 | description: Describe what actually happens. 28 | validations: 29 | required: false 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEAT]: " 5 | labels: feat 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe it** 11 | A clear and concise description of what the problem is. E.g. I always feel frustrated when [...] 12 | 13 | **Describe the solution you would like**. 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe the alternatives you have considered** A clear and concise description of what you want to happen. 17 | A clear and concise description of the alternative solutions or features you have considered. 18 | 19 | **Additional context** 20 | Add any additional context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new_algorithm.yml: -------------------------------------------------------------------------------- 1 | name: New Util type 2 | description: 'Suggest new util types, propose improvements to the project structure, discuss ideas for new implementations' 3 | title: '[NEW <>]: ' 4 | labels: ['feat'] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | ## Make sure that your topic is not a duplicate and that you follow our [contribution guidelines](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/blob/main/CONTRIBUTING.md) 10 | - type: textarea 11 | id: description 12 | attributes: 13 | label: Description of the Util Type 14 | description: Describe the algorithm, its use in a simple way and if possible an example of implementation. 15 | validations: 16 | required: true 17 | -------------------------------------------------------------------------------- /.github/workflows/Ci.yml: -------------------------------------------------------------------------------- 1 | name: Test Proyect 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | jobs: 11 | build: 12 | name: Code Style & Test 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - uses: actions/setup-node@v3 18 | with: 19 | node-version: 18.12.1 20 | cache: npm 21 | 22 | - name: 📦 Intall Dependencies 23 | run: npm i 24 | 25 | - name: 🧪 Run Test 26 | if: ${{ github.event_name == 'push' }} 27 | run: npm run test 28 | 29 | - name: 💄 Code Style 30 | run: npm run style 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | /.pnp 4 | .pnp.js 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | *.pem 15 | *.tgz 16 | 17 | # debug 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | # local env files 23 | .env*.local 24 | 25 | # vercel 26 | .vercel 27 | 28 | # typescript 29 | *.tsbuildinfo 30 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | set +e 5 | echo -e "\e[36m[Automated]\e[0m Running pre-commit hook" 6 | echo -e "\e[36m[Automated]\e[0m Stylelinting files" 7 | npm run lint 8 | if [ $? -ne 0 ]; then 9 | echo -e "\e[31m[Automated]\e[0m Stylelinting failed 💀" 10 | exit 1 11 | fi 12 | 13 | echo -e "\e[36m[Automated]\e[0m Testing files" 14 | npm run test-files 15 | if [ $? -ne 0 ]; then 16 | echo -e "\e[31m[Automated]\e[0m Testing failed 💀" 17 | exit 1 18 | fi 19 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | echo -e "\e[36m[Automated]\e[0m Running pre-push hook" 5 | npm run generate-markdown-tree 6 | if [ $? -ne 0 ]; then 7 | echo -e "\e[31m[Automated]\e[0m Generating markdown tree failed 💀" 8 | exit 1 9 | fi 10 | 11 | # Add generated files 12 | git add README.md 13 | git commit --amend --no-edit 14 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .gitattributes 3 | img 4 | /test 5 | /**/*.test.ts 6 | /scripts 7 | .vscode 8 | .github 9 | jest.config.ts 10 | .eslintrc 11 | .husky 12 | CODE_OF_CONDUCT.md 13 | README.md 14 | CONTRIBUTING.md 15 | LICENSE.md 16 | SECURITY.md 17 | *.tgz 18 | /docs 19 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [2.5.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v2.4.0...v2.5.0) (2023-07-12) 6 | 7 | ## [2.4.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.4.0...v2.4.0) (2023-07-12) 8 | 9 | 10 | ### Bug Fixes 11 | 12 | * :bug: fix error in workflow ([a2583d2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/a2583d297fbef145a4f01f1f7a648d6aa33b252e)) 13 | * :memo: fix error README ([97dc365](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/97dc36505c103494a473602130a5cbc234c30838)) 14 | * :memo: fix error README ([3eabeb1](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/3eabeb11a01e655cb971c5d9a87d64ae7ce24262)) 15 | * :memo: fix error README ([33a1346](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/33a1346b5cc735383ecedd758ddc1bb339d5b47c)) 16 | * :memo: fix error README ([f3f9dbc](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/f3f9dbc1a4b188e7a00b14321bbfc21e00449e38)) 17 | 18 | ## [2.3.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.4.0...v2.3.0) (2023-07-11) 19 | 20 | 21 | ### Bug Fixes 22 | 23 | * :bug: fix error in workflow ([a2583d2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/a2583d297fbef145a4f01f1f7a648d6aa33b252e)) 24 | * :memo: fix error README ([97dc365](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/97dc36505c103494a473602130a5cbc234c30838)) 25 | * :memo: fix error README ([3eabeb1](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/3eabeb11a01e655cb971c5d9a87d64ae7ce24262)) 26 | * :memo: fix error README ([33a1346](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/33a1346b5cc735383ecedd758ddc1bb339d5b47c)) 27 | * :memo: fix error README ([f3f9dbc](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/f3f9dbc1a4b188e7a00b14321bbfc21e00449e38)) 28 | 29 | ## [2.2.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.4.0...v2.2.0) (2023-07-07) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * :bug: fix error in workflow ([a2583d2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/a2583d297fbef145a4f01f1f7a648d6aa33b252e)) 35 | * :memo: fix error README ([97dc365](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/97dc36505c103494a473602130a5cbc234c30838)) 36 | * :memo: fix error README ([3eabeb1](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/3eabeb11a01e655cb971c5d9a87d64ae7ce24262)) 37 | * :memo: fix error README ([33a1346](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/33a1346b5cc735383ecedd758ddc1bb339d5b47c)) 38 | * :memo: fix error README ([f3f9dbc](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/f3f9dbc1a4b188e7a00b14321bbfc21e00449e38)) 39 | 40 | ## [2.1.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.4.0...v2.1.0) (2023-07-07) 41 | 42 | 43 | ### Bug Fixes 44 | 45 | * :bug: fix error in workflow ([a2583d2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/a2583d297fbef145a4f01f1f7a648d6aa33b252e)) 46 | * :memo: fix error README ([97dc365](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/97dc36505c103494a473602130a5cbc234c30838)) 47 | * :memo: fix error README ([3eabeb1](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/3eabeb11a01e655cb971c5d9a87d64ae7ce24262)) 48 | * :memo: fix error README ([33a1346](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/33a1346b5cc735383ecedd758ddc1bb339d5b47c)) 49 | * :memo: fix error README ([f3f9dbc](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/f3f9dbc1a4b188e7a00b14321bbfc21e00449e38)) 50 | 51 | ## [2.0.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.4.0...v2.0.0) (2023-07-04) 52 | 53 | ## [1.4.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.3.0...v1.4.0) (2023-07-03) 54 | 55 | ## [1.3.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.2.0...v1.3.0) (2023-07-02) 56 | 57 | ## [1.2.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.1.0...v1.2.0) (2023-07-02) 58 | 59 | ## [1.1.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.0.0...v1.1.0) (2023-07-02) 60 | 61 | 62 | ### Features 63 | 64 | * :green_heart: add CI staticsite. ([894603c](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/894603cfc7e3adee67227d527a1e160c7de84618)) 65 | 66 | 67 | ### Bug Fixes 68 | 69 | * :ambulance: hot fix of language in ISSUE_TEMPLATE ([55c0611](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/55c0611c0d519f46d6636a229b3289ab185a9c9a)) 70 | * :art: change image and url documentation link ([4e2069c](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/4e2069c62e26c9575a55fa7328fdbf254f58011e)) 71 | * :art: change image and url documentation link ([115b90b](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/115b90be6a07209e6fefe15e6f37af86d0f615a3)) 72 | * :art: change image and url documentation link ([df04f6e](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/df04f6e58ab638a9eae331156ad5f9ac4a3f51f9)) 73 | * :art: change image and url documentation link ([dbdc08f](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/dbdc08fec3999bd02092fea0863dd7c328dc9bfa)) 74 | * :art: change image and url documentation link ([244a7c2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/244a7c2e88ab3c4f3cc1eb2858ac018043902e82)) 75 | * :art: change image and url documentation link ([80e5f2e](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/80e5f2e3746a9ec021a19b6a258f024f5cdebe78)) 76 | * :art: fix opengraph images ([044de7b](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/044de7ba686d6acbe56f4c44a4a49aae4eb8bf49)) 77 | * :bug: fix error in PR ([87b0e64](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/87b0e6451410ffe5d98f40e3c85cf2652485a316)) 78 | * :bug: fix error in sociallinks ([655ae3c](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/655ae3c198a7a09a720083e9a709a81800fb0c5c)) 79 | * :memo: fix error README ([729985d](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/729985d87a99418cca0e2d72e19d873cde2e6815)) 80 | 81 | ## [1.0.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v1.0.0-alpha.0...v1.0.0) (2023-06-27) 82 | 83 | ## [1.0.0-alpha.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.2.2...v1.0.0-alpha.0) (2023-06-27) 84 | 85 | ### [0.2.2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.2.1...v0.2.2) (2023-06-27) 86 | 87 | ### [0.2.1](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.2.0...v0.2.1) (2023-06-27) 88 | 89 | ## [0.2.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.1.0...v0.2.0) (2023-06-27) 90 | 91 | ## [0.1.0](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.0.5...v0.1.0) (2023-06-27) 92 | 93 | ### [0.0.5](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.0.4...v0.0.5) (2023-06-27) 94 | 95 | 96 | ### Features 97 | 98 | * **keysoftype:** :sparkles: add KeysOfType Type ([73866b3](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/73866b3f3391d74bdd2347a844ac4d24dc8abfbd)) 99 | 100 | ### [0.0.4](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.0.3...v0.0.4) (2023-06-27) 101 | 102 | 103 | ### Features 104 | 105 | * **configs:** :wrench: add cz-configs and changelog ([d78f664](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/d78f6643fad72a9d6d8b269a2d1d156281fd5254)) 106 | 107 | ### [0.0.3](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.0.2...v0.0.3) (2023-06-27) 108 | 109 | ### [0.0.2](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/compare/v0.0.1...v0.0.2) (2023-06-27) 110 | 111 | 112 | ### Features 113 | 114 | * :sparkles: add ClassInstance Type ([5e88e7c](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/5e88e7cf7adbf6fcd2c0e35952e37fd0303dd7ba)) 115 | * :sparkles: add OverrideInterface Type ([41af357](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/41af3572f8a30c164fa1477c222667c925751c52)) 116 | * :sparkles: add script to validate struture in proyect ([2c0a759](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/2c0a759a3c370c792209fc9c8e54761af78cfaa6)) 117 | 118 | 119 | ### Bug Fixes 120 | 121 | * :art: Rename Ci.YML to Ci.yml ([3ee83de](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/3ee83de6256d2c9e282882c00167dd76901bc39c)) 122 | * :white_check_mark: fix ClassInstance test ([69c9ff3](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/69c9ff370d2063c47a39c43a144616b586c78f46)) 123 | * :white_check_mark: fix NonEmptyArray test ([f5cfc91](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/f5cfc9160be95555e50857ba2be330f907c27483)) 124 | * :white_check_mark: fix OverrideInterface test ([d63c220](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/commit/d63c22000c148730b7549c3356db2803bf677cb5)) 125 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct for Contributors 2 | ## Our Commitment 3 | We, as members, contributors, and leaders, commit to making participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnic origin, sexual characteristics, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 4 | 5 | We commit to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 6 | 7 | ## Our Standards 8 | Examples of behavior that contribute to creating a positive environment include: 9 | 10 | - Using welcoming and inclusive language 11 | - Respecting different viewpoints and experiences 12 | - Accepting constructive criticism gracefully 13 | - Focusing on what is best for the community 14 | - Showing empathy towards other community members 15 | 16 | Examples of unacceptable behavior by participants include: 17 | 18 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 19 | - Trolling, insulting/offensive comments, and personal or political attacks 20 | - Public or private harassment 21 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 22 | - Other conduct that could reasonably be considered inappropriate in a professional setting 23 | - Using or sharing company private code for personal or external public purposes 24 | 25 | ## Our Responsibilities 26 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 27 | 28 | ## Scope 29 | This Code of Conduct applies within all community spaces and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official community email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 30 | 31 | ## Enforcement 32 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at bryherrera55@gmail.com. All complaints will be reviewed and investigated promptly and fairly. 33 | 34 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 35 | 36 | ## Enforcement Guidelines 37 | Community leaders will follow these Community Impact Guidelines in determining the consequences of any action they deem in violation of this Code of Conduct: 38 | 39 | 1. Correction 40 | Community Impact: Use of inappropriate language or other behavior deemed unprofessional or inappropriate in the community. 41 | 42 | Consequence: A private, written warning from community leaders, clarifying the nature of the offense and providing an explanation of why the behavior was inappropriate. A public apology may be requested. 43 | 44 | 2. Warning 45 | Community Impact: A violation through a single incident or a series of actions. 46 | 47 | Consequence: A warning with consequences for continued behavior. Interaction with the people involved, including unsolicited interaction with Code of Conduct enforcers, may be limited for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violation of these terms may result in temporary or permanent bans. 48 | 49 | 3. Temporary Ban 50 | Community Impact: A serious violation of community standards, including sustained inappropriate behavior. 51 | 52 | Consequence: A temporary ban from any sort of public interaction or communication with the community for a specified period of time. During this period, no public or private interaction with the people involved, including unsolicited interaction with Code of Conduct enforcers, is allowed. Violation of these terms may result in a permanent ban. 53 | 54 | 4. Permanent Ban 55 | Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression towards or disdain for classes of individuals. 56 | 57 | Consequence: A permanent ban from any sort of public interaction within the community. 58 | 59 | ## Attribution 60 | 61 | This Code of Conduct is an adaptation of the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 62 | 63 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 64 | 65 | [homepage]: https://www.contributor-covenant.org 66 | 67 | For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 68 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution guidelines 2 | ## Before contributing 3 | Welcome to typescript-dev-utilsl! Before submitting your `pull requests`, be sure to read all the guidelines. If you have any questions about the contribution guidelines, don't hesitate to clearly state them in an issue. 4 | 5 | ## Contributing 6 | We're excited for you to consider contributing to our TypeScript Utils library! This repository is intended to be a reference for TypeScript developers and students worldwide. By becoming one of our contributors, you agree and confirm that: 7 | 8 | - **You have done your own work.** We do not tolerate plagiarism and will not merge any work that is plagiarized. 9 | - **If you take code from another repository, you must give credit to the original author.** Include a comment in your code indicating where you originally took the code from. 10 | - **Your work will be distributed under the MIT license once your pull request is merged.** You can read more about this license [here](https://opensource.org/licenses/MIT). 11 | - **Your work must comply with our style and coding standards.** This includes using proper and clear TypeScript types, writing meaningful and detailed comments, and organizing the code in a readable and maintainable way. 12 | - **New implementations are welcome.** For example, you can contribute new types/interfaces/implementations from advanced to complex. 13 | - **Improvements to existing comments and tests are also welcome.** We want our code to be as clear and understandable as possible, and our tests to be complete and effective. 14 | 15 | We look forward to seeing what you bring to our project! 16 | 17 | ## Contribution 18 | We welcome any contributions, from fixing grammatical errors to implementing advanced TypeScript types and features. 19 | 20 | If you make a pull request that resolves an open issue, please help keep our issues list manageable by adding fixes: #{$ISSUE_NO} to your commit. GitHub will use this tag to automatically close the issue when the PR is merged. 21 | 22 | ## Commit messages format 23 | We prefer that you use the following format for your commits: (`: :emoji:`): short description. If you need to provide more information, include it in the detailed commit message. 24 | 25 | For emojis, we recommend using the [gitmoji](https://gitmoji.dev/) list. 26 | 27 | Types of commits may include (but are not limited to): 28 | 29 | - docs: Changes that affect only the documentation. 30 | - feat: A new feature. 31 | - fix: A bug fix. 32 | - test: Addition or correction of tests. 33 | Examples: 34 | 35 | feat: :sparkles: add quicksort algorithm. 36 | fix: #123 :bug: correct incorrect error message. 37 | 38 | ## Tests 39 | Make sure your code works. To do this, we provide and use Jest to run unit tests on our implementations. Write tests for the functions you implement to make sure they work correctly, even after multiple code changes. 40 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2022 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Tpescript Dev Utils Logo 3 |

4 |
5 |

6 | Typescript Common Utils 7 |

8 |
9 |
10 | 11 | GitHub package.json dependency version (prod) 12 | 13 | 14 | npm 15 | 16 | 17 | License 18 | 19 | 20 | npm jest 21 | 22 |
23 | npm jest 24 |
25 |
26 | 27 | The Useful Types library is an indispensable tool for any developer who works with TypeScript on a regular basis. This library is designed to provide a wide range of common types used in everyday software development. 28 | 29 | Often, developers find themselves writing and rewriting the same types in different projects. This library aims to solve this problem by providing a complete set of well-defined and extensively tested types. 30 | 31 | The library of useful types consists of a number of type definitions ranging from the most basic to the most advanced. These include: 32 | 33 | - Basic types such as strings, numbers, and Booleans. 34 | - Complex types such as promises, functions and classes. 35 | - Utility types such as ClassConstructor, which allows the creation of instances of a given class. 36 | - Custom types that are common in many projects, such as user objects, settings, events, etc.a 37 | 38 | ## Project Status 39 | 40 | ![Alt](https://repobeats.axiom.co/api/embed/f12386845c45e3ad38341c8c31f11785d753a922.svg "Repobeats analytics image") 41 | 42 | ## Contributors 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
Eliseo F. Arévalo
Eliseo F. Arévalo

📖
Bryan Herrera ~ ርᚱ1ናተᛰ ᚻህᚥተპᚱ
Bryan Herrera ~ ርᚱ1ናተᛰ ᚻህᚥተპᚱ

🚧
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | ## Project Tree 67 | 68 | 69 | ```bash 70 | |-- .. 71 | | |-- .all-contributorsrc 72 | | |-- .editorconfig 73 | | |-- .eslintrc 74 | | |-- .npmignore 75 | | |-- .npmrc 76 | | |-- CHANGELOG.md 77 | | |-- CODE_OF_CONDUCT.md 78 | | |-- CONTRIBUTING.md 79 | | |-- index.ts 80 | | |-- jest.config.ts 81 | | |-- LICENSE.md 82 | | |-- package-lock.json 83 | | |-- package.json 84 | | |-- README.md 85 | | |-- SECURITY.md 86 | | |-- src 87 | | | |-- ArrayUtils 88 | | | | |-- AsReadOnlyArray 89 | | | | |-- index.ts 90 | | | | |-- index.ts 91 | | | | |-- NonEmptyArray 92 | | | | |-- index.ts 93 | | | |-- UnboxArray 94 | | | |-- index.ts 95 | | | |-- ClassUtils 96 | | | | |-- ClassConstructor 97 | | | | |-- index.ts 98 | | | | |-- ClassInstance 99 | | | | |-- index.ts 100 | | | | |-- index.ts 101 | | | | |-- MethodReturnType 102 | | | | |-- index.ts 103 | | | |-- PublicMethods 104 | | | |-- index.ts 105 | | |-- InterfaceUtils 106 | | | |-- DeepReadOnly 107 | | | |-- index.ts 108 | | | |-- index.ts 109 | | | |-- KeysOfType 110 | | | |-- index.ts 111 | | | |-- OmitByValueType 112 | | | |-- index.ts 113 | | | |-- OverrideInterface 114 | | | |-- index.ts 115 | | | |-- ReadonlyKeys 116 | | | |-- index.ts 117 | | | |-- RequireAtLeastOne 118 | | | |-- index.ts 119 | | | |-- UnionToIntersection 120 | | | |-- index.ts 121 | | |-- WritableKeys 122 | | |-- index.ts 123 | |-- tsconfig.json 124 | 125 | ``` 126 | 127 | 128 |
129 | 130 | 131 | Build with Love 132 | 133 | 134 | 135 | [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) 136 | 137 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | Reporting a Vulnerability 2 | If you discover a security vulnerability in this library please disclose. 3 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/typescript-common-utils/2c9fce696c4c06eec4d7ba19ebbe495cc6dc6ed7/docs/.nojekyll -------------------------------------------------------------------------------- /docs/ArrayUtils/AsReadOnlyArray.md: -------------------------------------------------------------------------------- 1 | # AsReadonlyArray 2 | `AsReadonlyArray` is a utility type that transforms an array type `T` into its corresponding readonly array type. This can be useful when you want to ensure that no mutations can be performed on the array. 3 | 4 | ## Definition 5 | ```typescript 6 | export type AsReadonlyArray = readonly [...T]; 7 | ``` 8 | 9 | ## Type Parameters 10 | - `T`: This type parameter represents the array type that you want to convert into a readonly array type. 11 | 12 | ## Return Value 13 | - `AsReadonlyArray`: The return type is a readonly array type that corresponds to `T`. Any attempt to perform array mutations (like push or pop) will result in a compile-time error. 14 | 15 | ## Example 16 | To use it with a specific array type: 17 | ```typescript 18 | type MyArray = number[]; 19 | 20 | type MyReadonlyArray = AsReadonlyArray; // readonly number[] 21 | ``` 22 | 23 | ## Example Implementation 24 | ```typescript 25 | import { AsReadonlyArray } from "typescript-dev-utils"; 26 | 27 | type MyTuple = [string, number, boolean]; 28 | 29 | // Creating a readonly tuple using AsReadonlyArray 30 | const tuple: AsReadonlyArray = ["string", 123, true]; 31 | // You can access the elements of the tuple but cannot modify it 32 | console.log(tuple[0]); // Returns: "string" 33 | console.log(tuple[1]); // Returns: 123 34 | console.log(tuple[2]); // Returns: true 35 | ``` 36 | 37 | ## Note 38 | `AsReadonlyArray` can be useful when you want to protect an array from being mutated. However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. -------------------------------------------------------------------------------- /docs/ArrayUtils/NonEmptyArray.md: -------------------------------------------------------------------------------- 1 | # NonEmptyArray 2 | `NonEmptyArray` is a utility type that represents an array containing at least one element. 3 | 4 | ## Definition 5 | 6 | ```ts 7 | export type NonEmptyArray = [T, ...T[]]; 8 | ``` 9 | 10 | ## Parameters 11 | - `T`: This type parameter represents the type of elements that the array can contain. 12 | 13 | ## Return Value 14 | - `NonEmptyArray`: The return type is an array of `T` containing at least one element. 15 | 16 | ## Examples 17 | ```ts 18 | // For use with a specific type: 19 | type MyNonEmptyArray = NonEmptyArray; 20 | const validArray: MyNonEmptyArray = [1]; // This is valid. 21 | const invalidArray: MyNonEmptyArray = []; // This will give a compilation error. 22 | 23 | // For use with type 'any': 24 | type AnyNonEmptyArray = NonEmptyArray; 25 | const anyValidArray: AnyNonEmptyArray = [1, 'string', {}, []]; // This is valid. 26 | const anyInvalidArray: AnyNonEmptyArray = []; // This will give a compilation error. 27 | ``` 28 | ## Example Implementation 29 | 30 | ```ts 31 | import { NonEmptyArray } from "typescript-dev-utils"; 32 | 33 | // Implementation of the NonEmptyArray type 34 | function isNonEmptyArray(arr: NonEmptyArray) { 35 | return arr[0]; 36 | } 37 | const arr = [1, 2, 3, 4, 5]; 38 | 39 | const first = isNonEmptyArray([arr[0]]); 40 | console.log(first) // Returns: 1 41 | console.log(arr.length) // Returns: 5 42 | 43 | ``` 44 | 45 | ## Note 46 | 47 | `NonEmptyArray` can be useful for guaranteeing the existence of at least one element in an array, but it cannot guarantee "non-emptiness" at runtime. If it is necessary to verify that an array is not empty at runtime, you will need to perform that check explicitly in your code. 48 | -------------------------------------------------------------------------------- /docs/ArrayUtils/UnboxArray.md: -------------------------------------------------------------------------------- 1 | # UnboxArray 2 | `UnboxArray` is a utility type that takes an array type and returns the type of the elements contained in that array. It is useful when you want to work with the type of elements in an array, rather than the array itself. 3 | 4 | ## Definition 5 | ```ts 6 | export type UnboxArray = T extends (infer U)[] ? U : T; 7 | ``` 8 | 9 | ## Parameters 10 | - `T`: This type parameter represents the type of the array you want to unpack. 11 | 12 | ## Return Type 13 | - `UnboxArray`: The return type is the type of the elements contained in the array `T`. If `T` is not an array type, the return type will be `T` unchanged. 14 | 15 | ## Examples 16 | For use with a specific array type: 17 | ```ts 18 | type MyArrayType = number[]; 19 | type MyElementType = UnboxArray; // number. 20 | 21 | // If you use it with a non-array type, you will get the same type: 22 | type MyNonArrayType = string; 23 | type MyNonArrayElementType = UnboxArray; // string 24 | ``` 25 | 26 | ## Example Implementation 27 | ```ts 28 | import { UnboxArray } from "typescript-dev-utils"; 29 | import { expectType } from "tsd"; 30 | 31 | // Function to get the type of the first element in an array 32 | const getElemento = (arr: T): UnboxArray => { 33 | return arr[0] as UnboxArray; 34 | }; 35 | 36 | // Example usage 37 | const miArray = ["Hola", "Mundo"]; 38 | 39 | const resultado = getElemento(miArray); 40 | 41 | // Type assertion and expectation 42 | expectType>(resultado); 43 | expect(resultado).toBe("Hola"); 44 | ``` 45 | 46 | ## Notes 47 | `UnboxArray` can be useful for working with array element types. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. -------------------------------------------------------------------------------- /docs/ClassUtils/ClassConstructor.md: -------------------------------------------------------------------------------- 1 | # Class Constructor 2 | `ClassConstructor` is a utility type that represents class construction in TypeScript. 3 | 4 | ## Definition 5 | 6 | ```ts 7 | export type ClassConstructor = new (...args: any[]) => T; 8 | ``` 9 | 10 | ## Parameters 11 | - `T`: This type parameter represents the type of the object that will be returned by the class constructor. By default it is `any`, which means it can be any type of object. However, if you want more control over the type that the constructor can return, you can provide a specific type using `ClassConstructor`. 12 | - `...args: any[]`: This represents any number of arguments that the class constructor can accept. Since this is an `any[]` type, the arguments can be of any type and in any number. 13 | 14 | ## Return Value 15 | - `T`: The return type is `T`, which is the same type that was provided to the type parameter when using `ClassConstructor`. In other words, the class constructor will return an object of type `T`. 16 | 17 | ## Examples 18 | ```ts 19 | type MyClassConstructor = ClassConstructor; 20 | const myClassInstance: MyClass = new MyClassConstructor(args); 21 | 22 | // For use with any type: 23 | type AnyClassConstructor = ClassConstructor; 24 | const anyClassInstance: any = new AnyClassConstructor(args); 25 | ``` 26 | ## Example Implementation 27 | ```ts 28 | import { ClassConstructor } from "typescript-dev-utils"; 29 | import { User } from "@/test/utils/UserClass"; 30 | 31 | // Implementation of the ClassConstructor type 32 | function instanceCreator(Cls: ClassConstructor, ...args: unknown[]): T { 33 | return new Cls(...args); 34 | } 35 | 36 | // Creating an instance of User using the ClassConstructor type. 37 | const user = instanceCreator(User, "John Doe", 30); 38 | 39 | // Verification of the User instance 40 | console.log(user instanceof User); // Returns: true 41 | console.log(user.name); // Returns: "John Doe". 42 | console.log(user.age); // Returns: 30 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/ClassUtils/ClassInstance.md: -------------------------------------------------------------------------------- 1 | # ClassInstance 2 | 3 | `ClassInstance` is a utility type that fetches the type of an instance from a given class. 4 | This type becomes useful when you have a reference to a class (constructor) and want to obtain the type of an instance from that class. 5 | 6 | ## Definition 7 | 8 | ```typescript 9 | export type ClassInstance = T extends new (...args: any[]) => infer R ? R : any 10 | ``` 11 | 12 | ## Parameters 13 | 14 | - `T`: This type parameter represents the class (constructor) from which you want to obtain the instance type. 15 | 16 | ## Return Value 17 | 18 | - `ClassInstance`: The return type is the instance type of the provided class. 19 | If `T` cannot be resolved to an instance type (for instance, if `T` is not a constructor), then the return type defaults to `any`. 20 | 21 | ## Examples 22 | 23 | ```typescript 24 | // For use with a specific class: 25 | class MyClass { 26 | prop: number; 27 | } 28 | type MyClassInstance = ClassInstance; 29 | const instance: MyClassInstance = new MyClass(); 30 | ``` 31 | 32 | > Note: `ClassInstance` cannot guarantee the type at runtime. If you need to check the type at runtime, you will have to perform that check explicitly in your code. 33 | 34 | ## Example Implementation 35 | 36 | ```typescript 37 | import { ClassInstance } from "typescript-dev-utils"; 38 | 39 | class MyClass { 40 | constructor(public message: string) {} 41 | } 42 | 43 | function createInstance any>(Cls: T, args: ConstructorParameters): ClassInstance { 44 | return new Cls(...args) as ClassInstance; 45 | } 46 | 47 | const instance = createInstance(MyClass, ["Hello World"]); 48 | console.log(instance instanceof MyClass); // Returns: true 49 | console.log(instance.message); // Returns: "Hello World" 50 | ``` 51 | -------------------------------------------------------------------------------- /docs/ClassUtils/MethodReturnType.md: -------------------------------------------------------------------------------- 1 | # MethodReturnType 2 | `MethodReturnType` is a utility type that gets the return type of a specific method within a `T` object. It is useful when you want to work with the return type of a specific method within an object. 3 | 4 | ## Definition 5 | ```typescript 6 | export type MethodReturnType = T[K] extends (...args: any[]) => infer R ? R : any; 7 | ``` 8 | 9 | ## Type Parameters 10 | - `T`: This type parameter represents the object you are interested in. 11 | - `K`: This type parameter represents the key of the method within the `T` object whose return type you are interested in obtaining. 12 | 13 | ## Return Value 14 | - `MethodReturnType`: The return type is the return type of the method that corresponds to the `K` key within the `T` object. If the key `K` does not correspond to a method in `T`, or if the method does not have an explicit return type, the return type will be `any`. 15 | 16 | ## Example 17 | For use with a specific object and method key: 18 | ```typescript 19 | class MyClass { 20 | greet(name: string): string { 21 | return `Hello, ${name}!`; 22 | } 23 | } 24 | 25 | type MyMethodReturnType = MethodReturnType; // string. 26 | ``` 27 | 28 | ## Example Implementation 29 | ```typescript 30 | import { MethodReturnType } from "typescript-dev-utils"; 31 | import { expectType } from "tsd"; 32 | 33 | class MyClass { 34 | greet(name: string): string { 35 | return `Hello, ${name}!`; 36 | } 37 | } 38 | 39 | const myInstance = new MyClass(); 40 | 41 | const result = myInstance.greet("John"); 42 | 43 | // We expect the type of the result to be the return type of the greet method 44 | expectType>(result); 45 | expect(result).toBe("Hello, John!"); 46 | ``` 47 | 48 | ## Note 49 | `MethodReturnType` can be useful for working with the return type of specific methods. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at run-time. -------------------------------------------------------------------------------- /docs/ClassUtils/PublicMethods.md: -------------------------------------------------------------------------------- 1 | # PublicMethods 2 | `PublicMethods` is a utility type that gets all the keys of a `T` object that correspond to public methods. It is useful when you want to work with the keys of an object that represent public methods. 3 | 4 | ## Definition 5 | ```ts 6 | export type PublicMethods = { 7 | [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never; 8 | }[keyof T]; 9 | ``` 10 | 11 | ## Parameters 12 | - `T`: This type parameter represents the object you are interested in. 13 | 14 | ## Return Type 15 | - `PublicMethods`: The return type is a union type of all keys in `T` that correspond to public methods. If there are no keys that are public methods, the return type will be `never`. 16 | 17 | ## Example 18 | For use with a specific object: 19 | ```ts 20 | class MyClass { 21 | public myPublicMethod(): void { } 22 | private myPrivateMethod(): void { } 23 | } 24 | 25 | type MyPublicMethods = PublicMethods; // "myPublicMethod". 26 | ``` 27 | 28 | ## Example Implementation 29 | ```ts 30 | import { PublicMethods } from "typescript-dev-utils"; 31 | import { expectType } from "tsd"; 32 | 33 | // Function to get the public methods of an object 34 | const obtenerMetodosPublicos = (obj: T): Array> => { 35 | const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).filter( 36 | key => typeof obj[key] === "function" && key !== "constructor" 37 | ) as Array>; 38 | return keys; 39 | }; 40 | 41 | // Example usage with a class 42 | class MiClase { 43 | public nombre: string = "Juan"; 44 | public apellido: string = "Perez"; 45 | 46 | public saludar() { 47 | return `Hola, mi nombre es ${this.nombre} ${this.apellido}`; 48 | } 49 | } 50 | 51 | const miObjeto = new MiClase(); 52 | 53 | const resultado = obtenerMetodosPublicos(miObjeto); 54 | 55 | // Type assertion and expectation 56 | expectType>>(resultado); 57 | expect(resultado).toEqual(["saludar"]); 58 | ``` 59 | 60 | ## Notes 61 | `PublicMethods` can be useful for working with object keys representing public methods. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. -------------------------------------------------------------------------------- /docs/InterfaceUtils/DeepReadOnly.md: -------------------------------------------------------------------------------- 1 | # DeepReadonly 2 | `DeepReadonly` is a utility type in TypeScript that takes a `T` type and makes all of its properties (and the properties of its properties, etc.) read-only. 3 | 4 | ## Definition 5 | ```ts 6 | export type DeepReadonly = { 7 | readonly [P in keyof T]: T[P] extends object ? DeepReadonly : T[P]; 8 | }; 9 | ``` 10 | ## Parameters 11 | - `T`: This type parameter represents any type of object you wish to convert to a read-only version. 12 | 13 | ## Return Type 14 | - `DeepReadonly`: The return type is a "deep" read-only version of `T`. Each property of `T` (and subproperties, etc.) will be read-only, which means that you cannot assign new values to them after creation. 15 | 16 | ## Examples 17 | For use with a single object: 18 | ```ts 19 | type MyReadonlyObj = DeepReadonly<{ prop: number, subObj: { prop2: string } }>; 20 | const obj: MyReadonlyObj = { prop: 1, subObj: { prop2: 'test' } }; 21 | // This will give an error, since 'prop' is read-only. 22 | obj.prop = 2; 23 | ``` 24 | 25 | ## Example Implementation 26 | ```ts 27 | import { DeepReadonly } from "typescript-dev-utils"; 28 | import { ExampleObjectOne } from "@/test/utils/ExampleObjectData"; 29 | 30 | // Transforming ExampleObjectOne to a read-only version using DeepReadonly 31 | function transformToReadonly(): DeepReadonly { 32 | return ExampleObjectOne; 33 | } 34 | 35 | // Obtaining the read-only data 36 | const readonlyData = transformToReadonly(); 37 | 38 | // Accessing properties (read-only) 39 | console.log(readonlyData.user.name); // Returns: "John Doe" 40 | console.log(readonlyData.user.details.age); // Returns: 30 41 | console.log(readonlyData.user.details.address.street); // Returns: "street 123" 42 | ``` 43 | 44 | ## Notes 45 | `DeepReadonly` can be very useful for working with complex object types and ensuring immutability. It recursively makes all properties of the object and its sub-properties read-only. However, it's important to be aware that using `DeepReadonly` extensively on large objects or deeply nested structures can have a performance impact. -------------------------------------------------------------------------------- /docs/InterfaceUtils/KeysOfType.md: -------------------------------------------------------------------------------- 1 | # KeysOfType 2 | `KeysOfType` is a utility type that gets all the keys of a `T` object whose values correspond to the `U` type. It is useful when you want to work with keys of an object that have a specific value type. 3 | 4 | ## Definition 5 | ```ts 6 | export type KeysOfType = { 7 | [K in keyof T]: T[K] extends U ? K : never; 8 | }[keyof T]; 9 | ``` 10 | 11 | ## Parameters 12 | - `T`: This type parameter represents the object you are interested in. 13 | - `U`: This type parameter represents the type of value you are looking for within the `T` object. 14 | 15 | ## Return Type 16 | - `KeysOfType`: The return type is a union type of all keys in `T` whose values correspond to type `U`. If there are no keys having a value of type `U`, the return type will be `never`. 17 | 18 | ## Examples 19 | For use with a specific object and value type: 20 | ```ts 21 | type MyType = { a: number; b: string; c: number; }; 22 | type NumberKeys = KeysOfType; // 'a' | 'c' 23 | ``` 24 | 25 | ## Example Implementation 26 | ```ts 27 | import { KeysOfType } from "typescript-dev-utils"; 28 | import { expectType } from "tsd"; 29 | 30 | interface IMiInterfaz { 31 | nombre: string; 32 | edad: number; 33 | direccion: string; 34 | activo: boolean; 35 | } 36 | 37 | // Function to get keys of type string from an object 38 | const getKeysOfString = (obj: T): Array> => { 39 | const keys = (Object.keys(obj) as Array).filter( 40 | key => typeof obj[key] === 'string' 41 | ) as Array>; 42 | return keys; 43 | }; 44 | 45 | // Example usage 46 | const miObjeto: IMiInterfaz = { nombre: "Juan", edad: 30, direccion: "Calle Falsa 123", activo: true }; 47 | 48 | const resultado = getKeysOfString(miObjeto); 49 | 50 | // Type assertion and expectation 51 | expectType>>(resultado); 52 | expect(resultado).toEqual(["nombre", "direccion"]); 53 | ``` 54 | 55 | ## Notes 56 | `KeysOfType` can be useful for working with object keys that have a specific type value. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at run-time. -------------------------------------------------------------------------------- /docs/InterfaceUtils/OmitByValueType.md: -------------------------------------------------------------------------------- 1 | # OmitByValueType 2 | `OmitByValueType` is a utility type that gets all keys of a `T` object whose values do not correspond to the `U` type. It is useful when you want to work with keys of an object that have a specific value type and exclude those that do not. 3 | 4 | ## Definition 5 | ```ts 6 | export type OmitByValueType = { 7 | [P in keyof T]: T[P] extends U ? never : P; 8 | }[keyof T]; 9 | ``` 10 | 11 | ## Parameters 12 | - `T`: This type parameter represents the object you are interested in. 13 | - `U`: This type parameter represents the type of value you are looking to exclude within the `T` object. 14 | 15 | ## Return Type 16 | - `OmitByValueType`: The return type is a union type of all keys in `T` whose values do not correspond to type `U`. If all keys have a value of type `U`, the return type will be `never`. 17 | 18 | ## Example 19 | For use with a specific object and value type: 20 | ```ts 21 | type MyType = { a: number; b: string; c: number; }; 22 | type NonNumberKeys = OmitByValueType; // 'b' 23 | ``` 24 | 25 | ## Example Implementation 26 | ```ts 27 | import { OmitByValueType } from "typescript-dev-utils"; 28 | import { expectType } from "tsd"; 29 | 30 | interface IMiInterfaz { 31 | nombre: string; 32 | edad: number; 33 | direccion: string; 34 | activo: boolean; 35 | } 36 | 37 | const getNonStringKeys = (obj: T): Array> => { 38 | const keys = (Object.keys(obj) as Array).filter( 39 | key => typeof obj[key] !== 'string' 40 | ) as Array>; 41 | return keys; 42 | }; 43 | 44 | const miObjeto: IMiInterfaz = { nombre: "Juan", edad: 30, direccion: "Calle Falsa 123", activo: true }; 45 | 46 | const resultado = getNonStringKeys(miObjeto); 47 | 48 | // Type assertion and expectation 49 | expectType>>(resultado); 50 | expect(resultado).toEqual(["edad", "activo"]); 51 | ``` 52 | 53 | ## Notes 54 | `OmitByValueType` can be useful for working with object keys that have a specific value type. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. -------------------------------------------------------------------------------- /docs/InterfaceUtils/OverrideInterface.md: -------------------------------------------------------------------------------- 1 | # OverrideInterface 2 | `OverrideInterface` is a utility type that takes two types `T` and `U` and combines their properties. However, if `T` and `U` have properties with the same keys, the properties of `U` overwrite those of `T`. 3 | 4 | ## Definition 5 | ```ts 6 | export type OverrideInterface = Omit & U; 7 | ``` 8 | 9 | ## Parameters 10 | - `T`: This type parameter represents the first type you want to combine. 11 | - `U`: This type parameter represents the second type, whose properties will overwrite those of `T` if they have the same keys. 12 | 13 | ## Return Type 14 | - `OverrideInterface`: The return type is a combination of `T` and `U`, but with the properties of `U` overwriting those of `T` if they have the same keys. 15 | 16 | ## Examples 17 | For use with two specific interface types: 18 | ```ts 19 | interface MyFirstType { a: number; b: string; } 20 | interface MySecondType { b: number; c: boolean; } 21 | type MyOverrideType = OverrideInterface; 22 | // The resulting type is { a: number; b: number; c: boolean; } 23 | ``` 24 | 25 | ## Example Implementation 26 | ```ts 27 | import { OverrideInterface } from "typescript-dev-utils"; 28 | import { expectType } from "tsd"; 29 | 30 | interface IFuente { 31 | nombre: string; 32 | edad: number; 33 | direccion: string; 34 | } 35 | 36 | interface IOverride { 37 | nombre: string; 38 | ciudad: string; 39 | } 40 | 41 | // Function to override properties from the source interface 42 | const getDatos = (fuente: T, override: U): OverrideInterface => { 43 | return { ...fuente, ...override }; 44 | }; 45 | 46 | // Example usage 47 | const fuente: IFuente = { nombre: "Juan", edad: 30, direccion: "Calle Falsa 123" }; 48 | const override: IOverride = { nombre: "Pedro", ciudad: "Madrid" }; 49 | 50 | const resultado = getDatos(fuente, override); 51 | 52 | // Type assertion and expectation 53 | expectType>(resultado); 54 | expect(resultado).toEqual({ nombre: "Pedro", edad: 30, direccion: "Calle Falsa 123", ciudad: "Madrid" }); 55 | ``` 56 | 57 | ## Notes 58 | `OverrideInterface` can be useful for modifying existing types or for combining types with possibly matching properties. Note, however, that TypeScript is a compile-time type system and cannot guarantee run-time consistency. -------------------------------------------------------------------------------- /docs/InterfaceUtils/ReadonlyKeys.md: -------------------------------------------------------------------------------- 1 | # ReadonlyKeys 2 | `ReadonlyKeys` is a utility type in TypeScript that retrieves all keys of an object `T` that represent readonly properties. It's helpful when you want to work with keys of an object representing properties that cannot be altered (are readonly). 3 | 4 | ## Definition 5 | ```typescript 6 | export type ReadonlyKeys = { [P in keyof T]: T extends ReadonlyArray ? P : never }[keyof T]; 7 | ``` 8 | 9 | ## Type Parameters 10 | - `T`: This type parameter represents the object from which you're interested in obtaining the keys of readonly properties. 11 | 12 | ## Return Value 13 | - `ReadonlyKeys`: The return type is a union type of all keys in `T` that correspond to readonly properties. If there are no keys that are readonly properties, the return type will be 'never'. 14 | 15 | ## Example 16 | To use it with a specific object: 17 | ```typescript 18 | type MyObject = { 19 | readonly myReadonlyProperty: number; 20 | myWritableProperty: string; 21 | }; 22 | 23 | type MyReadonlyKeys = ReadonlyKeys; // "myReadonlyProperty" 24 | ``` 25 | 26 | ## Example Implementation 27 | ```typescript 28 | import { ReadonlyKeys } from "typescript-dev-utils"; 29 | 30 | type MyObject = { 31 | readonly myReadonlyProperty: number; 32 | myWritableProperty: string; 33 | }; 34 | 35 | // Retrieve the keys of readonly properties 36 | type MyReadonlyKeys = ReadonlyKeys; 37 | 38 | // Type assertion and expectation 39 | expect<"myReadonlyProperty">(null as MyReadonlyKeys); 40 | ``` 41 | 42 | ## Note 43 | `ReadonlyKeys` can be useful when working with keys of objects representing readonly properties. However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. -------------------------------------------------------------------------------- /docs/InterfaceUtils/RequireAtLeastOne.md: -------------------------------------------------------------------------------- 1 | # RequireAtLeastOne 2 | `RequireAtLeastOne` is a utility type that enforces that at least one of the properties of an object `T` should be present. The type parameter `Keys` represents the keys that you're interested in. If it's not explicitly provided, it defaults to `keyof T`, meaning it will consider all keys in `T`. 3 | 4 | ## Definition 5 | ```typescript 6 | export type RequireAtLeastOne = 7 | Pick> 8 | & { 9 | [K in Keys]-?: Required> & Partial>> 10 | }[Keys] 11 | ``` 12 | 13 | ## Type Parameters 14 | - `T`: This type parameter represents the object that you're interested in. 15 | - `Keys`: This optional type parameter represents the keys of `T` that should have at least one defined. If not specified, it defaults to `keyof T`, considering all keys in `T`. 16 | 17 | ## Return Value 18 | - `RequireAtLeastOne`: The return type is an object type that enforces that at least one of the specified keys should be present in the object. 19 | 20 | ## Example 21 | To use it with a specific object type and keys: 22 | ```typescript 23 | interface MyInterface { 24 | prop1?: number; 25 | prop2?: string; 26 | prop3?: boolean; 27 | } 28 | 29 | type MyInterfaceWithAtLeastOne = RequireAtLeastOne; 30 | // An object of this type must have either 'prop1' or 'prop2', or both. 31 | ``` 32 | 33 | ## Example Implementation 34 | ```typescript 35 | import { RequireAtLeastOne } from "typescript-dev-utils"; 36 | 37 | interface MyInterface { 38 | prop1?: number; 39 | prop2?: string; 40 | prop3?: boolean; 41 | } 42 | 43 | // Creating an object with at least one property from the specified keys 44 | const obj1: RequireAtLeastOne = { 45 | prop1: 123, 46 | }; 47 | 48 | const obj2: RequireAtLeastOne = { 49 | prop2: "hello", 50 | }; 51 | 52 | const obj3: RequireAtLeastOne = { 53 | prop1: 123, 54 | prop2: "hello", 55 | }; 56 | ``` 57 | 58 | ## Note 59 | `RequireAtLeastOne` can be useful when you want to enforce that at least one of certain properties must be present in an object. However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. 60 | -------------------------------------------------------------------------------- /docs/InterfaceUtils/UnionToIntersection.md: -------------------------------------------------------------------------------- 1 | # UnionToIntersection 2 | `UnionToIntersection` is a utility type that takes a union of types and converts them into an intersection of types. It is useful when you have a union of types and need to work with a type that includes all the properties of each type in the union. 3 | 4 | ## Definition 5 | ```ts 6 | export type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; 7 | ``` 8 | 9 | ## Parameters 10 | - `U`: This type parameter represents the union of types you want to convert to an intersection. 11 | 12 | ## Return Type 13 | - `UnionToIntersection`: The return type is an intersection of all types in the union `U`. If `U` is not a union of types, the return type will be `U` unchanged. 14 | 15 | ## Example 16 | To use with a union of types: 17 | ```ts 18 | type MyUnion = { a: number; } | { b: string; }; 19 | type MyIntersection = UnionToIntersection; // { a: number; } & { { b: string; } 20 | ``` 21 | 22 | ## Example Implementation 23 | ```ts 24 | import { UnionToIntersection } from "typescript-dev-utils"; 25 | import { expectType, expectError } from "tsd"; 26 | 27 | type MiUnion = { nombre: string } | { apellido: string }; 28 | 29 | const mergeObjects = (...objs: T): UnionToIntersection => { 30 | return objs.reduce((acc, obj) => ({ ...acc, ...obj }), {} as any); 31 | }; 32 | 33 | const miObjeto1 = { nombre: "Juan" }; 34 | const miObjeto2 = { apellido: "Perez" }; 35 | const resultado = mergeObjects(miObjeto1, miObjeto2); 36 | 37 | // Type assertion and expectation 38 | expectType>(resultado); 39 | expect(resultado).toEqual({ nombre: "Juan", apellido: "Perez" }); 40 | ``` 41 | 42 | ## Notes 43 | `UnionToIntersection` can be useful for working with type intersections from type unions. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. -------------------------------------------------------------------------------- /docs/InterfaceUtils/WritableKeys.md: -------------------------------------------------------------------------------- 1 | # WritableKeys 2 | `WritableKeys` is a utility type that retrieves all keys of an object `T` that represent writable properties (i.e., not read-only). It's useful when you want to work with keys of an object representing properties that can be altered. 3 | 4 | ## Definition 5 | ```typescript 6 | export type WritableKeys = { 7 | [P in keyof T]: ReadonlyArray extends ReadonlyArray ? never : P; 8 | }[keyof T]; 9 | ``` 10 | 11 | ## Type Parameters 12 | - `T`: This type parameter represents the object from which you're interested in obtaining the keys of writable properties. 13 | 14 | ## Return Value 15 | - `WritableKeys`: The return type is a union type of all keys in `T` that correspond to writable properties. If there are no keys that are writable properties, the return type will be 'never'. 16 | 17 | ## Example 18 | To use it with a specific object: 19 | ```typescript 20 | type MyObject = { 21 | readonly myReadonlyProperty: number; 22 | myWritableProperty: string; 23 | }; 24 | 25 | type MyWritableKeys = WritableKeys; // "myWritableProperty" 26 | ``` 27 | 28 | ## Example Implementation 29 | ```typescript 30 | type MyObject = { 31 | readonly myReadonlyProperty: number; 32 | myWritableProperty: string; 33 | }; 34 | 35 | const obj: MyObject = { 36 | myReadonlyProperty: 123, 37 | myWritableProperty: "hello", 38 | }; 39 | 40 | // Get the writable keys of MyObject 41 | type MyWritableKeys = WritableKeys; // "myWritableProperty" 42 | ``` 43 | 44 | ## Note 45 | `WritableKeys` can be useful when working with keys of objects representing writable properties. However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 |

2 | Tpescript Dev Utils Logo 3 |

4 |
5 |

6 | Typescript Common Utils 7 |

8 |
9 | 23 | 24 | The Useful Types library is an indispensable tool for any developer who works with TypeScript on a regular basis. This library is designed to provide a wide range of common types used in everyday software development. 25 | 26 | Often, developers find themselves writing and rewriting the same types in different projects. This library aims to solve this problem by providing a complete set of well-defined and extensively tested types. 27 | 28 | The library of useful types consists of a number of type definitions ranging from the most basic to the most advanced. These include: 29 | 30 | - Basic types such as strings, numbers, and Booleans. 31 | - Complex types such as promises, functions and classes. 32 | - Utility types such as ClassConstructor, which allows the creation of instances of a given class. 33 | - Custom types that are common in many projects, such as user objects, settings, events, etc.a 34 | 35 | 36 | License 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /docs/_coverpage.md: -------------------------------------------------------------------------------- 1 |

2 | Tpescript Dev Utils Logo 3 |

4 | 5 | # Typescript Dev Utils 6 | 7 | > A most useful typescript library of developers. 8 | 9 | [GitHub](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/) 10 | [Get Started](/#typescript-common-utils) 11 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | - [Quick Start](quickstart.md) 2 | - **Utils** 3 | - Class Util 4 | - [ClassConstructor](ClassUtils/ClassConstructor.md) 5 | - [ClassInstance](ClassUtils/ClassInstance.md) 6 | - [PublicMethods](ClassUtils/PublicMethods.md) 7 | - [MethodReturnType](ClassUtils/MethodReturnType.md) 8 | - Array Utils 9 | - [NonEmptyArray](ArrayUtils/NonEmptyArray.md) 10 | - [UnboxArray](ArrayUtils/UnboxArray.md) 11 | - [AsReadOnlyArray](ArrayUtils/AsReadOnlyArray.md.md) 12 | - InterfaceUtils 13 | - [DeepReadOnly](InterfaceUtils/DeepReadOnly.md) 14 | - [KeysOfType](InterfaceUtils/KeysOfType.md) 15 | - [OverrideInterface](InterfaceUtils/OverrideInterface.md) 16 | - [OmitByValueType](InterfaceUtils/OmitByValueType.md) 17 | - [UnionToIntersection](InterfaceUtils/UnionToIntersection.md) 18 | - [ReadonlyKeys](InterfaceUtils/ReadonlyKeys.md) 19 | - [RequireAtLeastOne](InterfaceUtils/RequireAtLeastOne.md) 20 | - [WritableKeys](InterfaceUtils/WritableKeys.md.md) 21 | - **Links** 22 | - [![Github](assets/img/github.svg)Github](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/) 23 | - [![NPM](assets/img/npm.svg)NPM](https://www.npmjs.com/package/typescript-dev-utils) 24 | -------------------------------------------------------------------------------- /docs/assets/img/LOGO-BANNER.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/typescript-common-utils/2c9fce696c4c06eec4d7ba19ebbe495cc6dc6ed7/docs/assets/img/LOGO-BANNER.png -------------------------------------------------------------------------------- /docs/assets/img/LOGO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/typescript-common-utils/2c9fce696c4c06eec4d7ba19ebbe495cc6dc6ed7/docs/assets/img/LOGO.png -------------------------------------------------------------------------------- /docs/assets/img/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/typescript-common-utils/2c9fce696c4c06eec4d7ba19ebbe495cc6dc6ed7/docs/assets/img/banner.jpg -------------------------------------------------------------------------------- /docs/assets/img/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/assets/img/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/assets/img/npm.svg: -------------------------------------------------------------------------------- 1 | NPM icon -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Typescript Dev Utils | Documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
Please wait...
38 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/quickstart.md: -------------------------------------------------------------------------------- 1 | # Quick start 2 | 3 | ## Installation 4 | 5 | To install the package, run the following command in the terminal: 6 | ```bash 7 | npm i typescript-dev-utils 8 | ``` 9 | -------------------------------------------------------------------------------- /docs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /test/ 3 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export * from "./src/ClassUtils"; 2 | export * from "./src/InterfaceUtils"; 3 | export * from "./src/ArrayUtils"; 4 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "@jest/types"; 2 | // Sync object 3 | const config: Config.InitialOptions = { 4 | verbose: true, 5 | transform: { 6 | "^.+\\.tsx?$": "ts-jest" 7 | } 8 | }; 9 | export default config; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-dev-utils", 3 | "version": "2.5.0", 4 | "description": "Library that makes available many useful and common types for regular typescript developers.", 5 | "main": "index.ts", 6 | "author": "Bryan Herrera ", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/Bryan-Herrera-DEV/typescript-common-utils" 10 | }, 11 | "scripts": { 12 | "test": "jest --no-cache", 13 | "test-changed": "jest --onlyChanged", 14 | "lint": "eslint . --ext .ts", 15 | "style": "npm run lint -- --fix", 16 | "prepare": "husky install", 17 | "release": "standard-version", 18 | "release:major": "npm run release -- --release-as major", 19 | "release:minor": "npm run release -- --release-as minor", 20 | "release:patch": "npm run release -- --release-as patch", 21 | "release:alpha": "npm run release -- --prerelease alpha", 22 | "release:breaking-changes": "npm run release -- --release-as major --prerelease alpha", 23 | "publish": "npm push --follow-tags main", 24 | "test-files": "node scripts/ValidateTest.mjs", 25 | "generate-markdown-tree": "node scripts/MarkdownGenerateTree.js" 26 | }, 27 | "keywords": [ 28 | "typescript", 29 | "utils", 30 | "common", 31 | "types", 32 | "typescript-common-utils", 33 | "library" 34 | ], 35 | "license": "MIT", 36 | "dependencies": { 37 | "typescript": "^5.1.3" 38 | }, 39 | "devDependencies": { 40 | "@types/jest": "^29.2.2", 41 | "@typescript-eslint/eslint-plugin": "^5.42.1", 42 | "@typescript-eslint/parser": "^5.42.1", 43 | "babel-jest": "^29.2.2", 44 | "commitizen": "^4.3.0", 45 | "cz-conventional-changelog": "^3.3.0", 46 | "cz-customizable": "^7.0.0", 47 | "eslint": "^8.27.0", 48 | "globby": "^13.2.0", 49 | "husky": "^8.0.3", 50 | "jest": "^29.2.2", 51 | "standard-version": "^9.5.0", 52 | "ts-jest": "^29.0.3", 53 | "ts-node": "^10.9.1", 54 | "tsd": "^0.28.1" 55 | }, 56 | "engines": { 57 | "node": ">=16.0.0" 58 | }, 59 | "bugs": { 60 | "url": "https://github.com/Bryan-Herrera-DEV/typescript-common-utils/issues" 61 | }, 62 | "homepage": "https://github.com/Bryan-Herrera-DEV/typescript-common-utils#readme", 63 | "config": { 64 | "commitizen": { 65 | "path": "./node_modules/cz-conventional-changelog" 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /scripts/MarkdownGenerateTree.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 The TypescriptCommonUtils Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | const fs = require('fs').promises; 6 | const path = require('path'); 7 | 8 | /** 9 | * Get the size of a file 10 | * @param {string} filePath - The path of the file 11 | * @returns {string} The size of the file in bytes 12 | */ 13 | async function getFileSize(filePath) { 14 | const stats = await fs.stat(filePath); 15 | return `${stats.size} bytes`; 16 | } 17 | 18 | /** 19 | * Generate a README file with a project tree structure 20 | * @param {Object} config - The configuration object 21 | * @param {string} config.rootDir - The root directory of your project 22 | * @param {string} [config.outputPath] - The output path for the README.md file 23 | * @param {RegExp[]} [config.ignoreRegexArray] - An array of RegExp to ignore certain directories or files 24 | * @param {string} [config.startTag] - The start tag in the README.md to insert the project tree structure 25 | * @param {string} [config.endTag] - The end tag in the README.md to insert the project tree structure 26 | * @param {Object} [config.displayConfig] - The display configuration object 27 | * @param {string} [config.displayConfig.theme] - The theme of the project tree structure ('classic' | 'minimalist' | 'emoji' | 'tabulation') 28 | * @param {boolean} [config.displayConfig.showExtension] - Whether to show the file extension 29 | * @param {boolean} [config.displayConfig.showFileSize] - Whether to show the file size 30 | */ 31 | async function generateReadme({ rootDir, outputPath = path.join(rootDir, 'README.md'), ignoreRegexArray = [], startTag = "", endTag = "", displayConfig = {} }) { 32 | const defaultDisplayConfig = { 33 | theme: 'classic', 34 | showExtension: true, 35 | showFileSize: false 36 | }; 37 | const mergedDisplayConfig = { ...defaultDisplayConfig, ...displayConfig }; 38 | 39 | try { 40 | const tree = await generateTree(rootDir, ignoreRegexArray, mergedDisplayConfig); 41 | const readmeContent = generateReadmeContent(tree, mergedDisplayConfig); 42 | const currentReadmeContent = await fs.readFile(outputPath, 'utf-8'); 43 | const updatedReadmeContent = insertIntoReadme(currentReadmeContent, readmeContent, startTag, endTag); 44 | await fs.writeFile(outputPath, updatedReadmeContent); 45 | console.log(`README.md generated successfully at ${outputPath}`); 46 | } catch (error) { 47 | console.error(`Failed to generate README.md: ${error}`); 48 | } 49 | } 50 | 51 | async function generateTree(dir, ignoreRegexArray, displayConfig) { 52 | const basename = path.basename(dir); 53 | 54 | if (ignoreRegexArray.some(regex => regex.test(basename))) { 55 | return null; 56 | } 57 | 58 | const stats = await fs.stat(dir); 59 | if (!stats.isDirectory()) { 60 | return { 61 | name: basename, 62 | type: 'file', 63 | extension: displayConfig.showExtension ? path.extname(dir) : '', 64 | size: displayConfig.showFileSize ? await getFileSize(dir) : '' 65 | }; 66 | } 67 | 68 | const files = await fs.readdir(dir); 69 | const tree = { 70 | name: basename, 71 | type: 'directory', 72 | children: [] 73 | }; 74 | 75 | for (const file of files) { 76 | const filePath = path.join(dir, file); 77 | const childTree = await generateTree(filePath, ignoreRegexArray, displayConfig); 78 | if (childTree) { 79 | tree.children.push(childTree); 80 | } 81 | } 82 | 83 | return tree; 84 | } 85 | 86 | function generateReadmeContent(tree, displayConfig, indent = '') { 87 | if (!tree) { 88 | return ''; 89 | } 90 | 91 | const name = tree.name; 92 | let content = `${indent}${getPrefix(tree.type, displayConfig.theme)} ${name}`; // TODO: FIX ${tree.extension} OF UNDEFINED 93 | 94 | if (tree.size) { 95 | content += ` (${tree.size})`; 96 | } 97 | 98 | content += '\n'; 99 | 100 | if (tree.type === 'directory') { 101 | tree.children.forEach((child, index) => { 102 | const isLastChild = index === tree.children.length - 1; 103 | const childIndent = indent + (isLastChild ? ' ' : getIndent(tree.type, displayConfig.theme)); 104 | content += generateReadmeContent(child, displayConfig, childIndent); 105 | }); 106 | } 107 | 108 | return content; 109 | } 110 | 111 | function getPrefix(type, theme) { 112 | switch (theme) { 113 | case 'tabulation': 114 | return type === 'directory' ? '+-- ' : '|-- '; 115 | case 'minimalist': 116 | return type === 'directory' ? '+' : '-'; 117 | case 'emoji': 118 | return type === 'directory' ? '📁 ' : '📄 '; 119 | case 'classic': 120 | default: 121 | return '|--'; 122 | } 123 | } 124 | 125 | function getIndent(type, theme) { 126 | switch (theme) { 127 | case 'tabulation': 128 | return type === 'directory' ? ' ' : '| '; 129 | case 'minimalist': 130 | return ' '; 131 | case 'emoji': 132 | return ' '; 133 | case 'classic': 134 | default: 135 | return '| '; 136 | } 137 | } 138 | 139 | function insertIntoReadme(readmeContent, insertContent, startTag, endTag) { 140 | const startTagIndex = readmeContent.indexOf(startTag); 141 | const endTagIndex = readmeContent.indexOf(endTag); 142 | 143 | if (startTagIndex === -1 || endTagIndex === -1) { 144 | throw new Error(`Cannot find the start and end tags in README.md`); 145 | } 146 | 147 | const beforeTagContent = readmeContent.substring(0, startTagIndex + startTag.length); 148 | const afterTagContent = readmeContent.substring(endTagIndex); 149 | 150 | const wrappedInsertContent = `\n\n\`\`\`bash\n${insertContent}\n\`\`\`\n\n`; 151 | 152 | return beforeTagContent + wrappedInsertContent + afterTagContent; 153 | } 154 | 155 | const config = { 156 | rootDir: __dirname + '/../', 157 | ignoreRegexArray: [/node_modules/, /\.git/, /\.vscode/, /dist/, /coverage/, /\.husky/, /docs/, /scripts/, /test/, /\.tgz/], 158 | displayConfig: { 159 | theme: 'classic', 160 | showExtension: true, // TODO: FIX ${tree.extension} OF UNDEFINED 161 | showFileSize: false 162 | } 163 | }; 164 | 165 | generateReadme(config); 166 | -------------------------------------------------------------------------------- /scripts/ValidateTest.mjs: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import { globby } from "globby"; 3 | 4 | function validateFolderSpecialCharacters(filePath, fileName) { 5 | const regex = new RegExp(/[^a-zA-Z\.]/); 6 | if (regex.test(filePath)) { 7 | throw new Error( 8 | `Folder name '${filePath}' contains special characters. Please remove them.` 9 | ); 10 | } 11 | if (regex.test(fileName)) { 12 | throw new Error( 13 | `File name '${fileName}' contains special characters. Please remove them.` 14 | ); 15 | } 16 | } 17 | 18 | function validateFolderAndFileNames(filePath, fileName) { 19 | if (filePath === "src") { 20 | throw new Error("Folder name cannot be 'src'"); 21 | } 22 | if (!fileName.toLowerCase().includes(".test.ts")) { 23 | throw new Error( 24 | `File name '${fileName}' does not contain '.test'. Please add it.` 25 | ); 26 | } 27 | if (fileName.toLowerCase().split(".")[0] !== filePath.toLowerCase()) { 28 | throw new Error( 29 | `Folder name '${filePath}' does not match file name '${fileName}'` 30 | ); 31 | } 32 | } 33 | 34 | function execute(filePaths) { 35 | for (let filepath of filePaths) { 36 | let filename = path.basename(filepath); 37 | filepath = path.dirname(filepath); 38 | filepath = filepath.replace("src/", ""); 39 | filepath = filepath.split("/")[1]; 40 | if (filepath && filename !== "index.ts") { 41 | validateFolderAndFileNames(filepath, filename); 42 | } 43 | if (filepath && filename === "index.ts") { 44 | validateFolderSpecialCharacters(filepath, filename); 45 | } 46 | } 47 | return filePaths; 48 | } 49 | 50 | // get paths of all .ts files - excluding node_modules, the .github folder, tests and config stuff 51 | globby([ 52 | "src/ArrayUtils/**/*.ts", 53 | "src/ClassUtils/**/*.ts", 54 | "src/InterfaceUtils/**/*.ts", 55 | "!(node_modules|.github)/**/*", 56 | "!**/test/**/*", 57 | "!*.config.ts", 58 | ]) 59 | // create markdown content 60 | .then(execute); 61 | -------------------------------------------------------------------------------- /src/ArrayUtils/AsReadOnlyArray/AsReadOnlyArray.test.ts: -------------------------------------------------------------------------------- 1 | import { AsReadonlyArray } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | describe("[Test] AsReadonly", () => { 5 | it("returns a readonly tuple", () => { 6 | type MyTuple = [string, number, boolean]; 7 | 8 | type ReadonlyTuple = AsReadonlyArray; 9 | 10 | expectType({} as ReadonlyTuple); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/ArrayUtils/AsReadOnlyArray/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * AsReadonly is a utility type that transforms an array type `T` into its corresponding readonly array type. 3 | * This can be useful when you want to ensure that no mutations can be performed on the array. 4 | * 5 | * @template T - This type parameter represents the array type that you want to convert into a readonly array type. 6 | * 7 | * @returns {AsReadonly} - The return type is a readonly array type that corresponds to `T`. 8 | * Any attempt to perform array mutations (like push or pop) will result in a compile-time error. 9 | * 10 | * @example 11 | * // To use it with a specific array type: 12 | * type MyArray = number[]; 13 | * 14 | * type MyReadonlyArray = AsReadonly; // readonly number[] 15 | * 16 | * @note AsReadonly can be useful when you want to protect an array from being mutated. 17 | * However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. 18 | */ 19 | export type AsReadonlyArray = readonly [...T]; 20 | -------------------------------------------------------------------------------- /src/ArrayUtils/NonEmptyArray/NonEmptyArray.test.ts: -------------------------------------------------------------------------------- 1 | import { NonEmptyArray } from "./"; 2 | function esNonEmptyArray(arr: NonEmptyArray) { 3 | return arr[0]; 4 | } 5 | describe("[Test] NonEmptyArray", () => { 6 | it("returns the first element of a non-empty array", () => { 7 | const arr = [1, 2, 3, 4, 5]; 8 | if (arr.length > 0) { 9 | const primer = esNonEmptyArray([arr[0]]); 10 | expect(primer).toBe(1); 11 | 12 | expect(arr.length).toBeGreaterThan(0); 13 | } 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/ArrayUtils/NonEmptyArray/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * NonEmptyArray is a utility type that represents an array containing at least one element. 3 | * 4 | * @template T - This type parameter represents the type of elements that the array can contain. 5 | * 6 | * @returns {NonEmptyArray} - The return type is an array of `T` containing at least one element. 7 | * 8 | * @example 9 | * // For use with a specific type: 10 | * type MyNonEmptyArray = NonEmptyArray; 11 | * const validArray: MyNonEmptyArray = [1]; // This is valid. 12 | * const invalidArray: MyNonEmptyArray = []; // This will give a compilation error. 13 | * 14 | * // For use with type 'any': 15 | * type AnyNonEmptyArray = NonEmptyArray; 16 | * const anyValidArray: AnyNonEmptyArray = [1, 'string', {}, []]; // This is valid. 17 | * const anyInvalidArray: AnyNonEmptyArray = []; // This will give a compilation error. 18 | * 19 | * @note NonEmptyArray can be useful for guaranteeing the existence of at least one element in an array, but it cannot guarantee "non-emptiness" at runtime. 20 | * If it is necessary to verify that an array is not empty at runtime, you will need to perform that check explicitly in your code. 21 | */ 22 | export type NonEmptyArray = [T, ...T[]]; 23 | -------------------------------------------------------------------------------- /src/ArrayUtils/UnboxArray/UnboxArray.test.ts: -------------------------------------------------------------------------------- 1 | import { UnboxArray } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | describe("[Test] UnboxArray", () => { 5 | it("returns the type of elements in an array", () => { 6 | const getElemento = (arr: T): UnboxArray => { 7 | return arr[0] as UnboxArray; 8 | }; 9 | 10 | const miArray = ["Hola", "Mundo"]; 11 | 12 | const resultado = getElemento(miArray); 13 | 14 | // Esperamos que el resultado sea de tipo UnboxArray 15 | expectType>(resultado); 16 | expect(resultado).toBe("Hola"); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/ArrayUtils/UnboxArray/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * UnboxArray is a utility type that takes an array type and returns the type of the elements contained in that array. 3 | * It is useful when you want to work with the type of elements in an array, rather than the array itself. 4 | * 5 | * @template T - This type parameter represents the type of array you want to unpack. 6 | * 7 | * @returns {UnboxArray} - The return type is the type of the elements contained in the array `T`. 8 | * If `T` is not an array type, the return type will be `T` unchanged. 9 | * 10 | * @example 11 | * // For use with a specific array type: 12 | * type MyArrayType = number[]; 13 | * type MyElementType = UnboxArray; // number. 14 | * 15 | * // If you use it with a non-array type, you will get the same type: 16 | * type MyNonArrayType = string; 17 | * type MyNonArrayElementType = UnboxArray; // string 18 | * 19 | * @note UnboxArray can be useful for working with array element types. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. 20 | */ 21 | export type UnboxArray = T extends (infer U)[] ? U : T; 22 | -------------------------------------------------------------------------------- /src/ArrayUtils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./NonEmptyArray"; 2 | -------------------------------------------------------------------------------- /src/ClassUtils/ClassConstructor/ClassConstructor.test.ts: -------------------------------------------------------------------------------- 1 | import { ClassConstructor } from "."; 2 | import { Usuario } from "../../../test/utils/UsuarioClass"; 3 | 4 | describe("[Test] ClassConstructor", () => { 5 | it("Create User Instance", () => { 6 | function instanciaCreador(Cls: ClassConstructor, ...args: unknown[]): T { 7 | return new Cls(...args); 8 | } 9 | 10 | const usuario = instanciaCreador(Usuario, "John Doe", 30); 11 | 12 | expect(usuario).toBeInstanceOf(Usuario); 13 | expect(usuario.nombre).toEqual("John Doe"); 14 | expect(usuario.edad).toEqual(30); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/ClassUtils/ClassConstructor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a utility type for representing class construction in TypeScript. 3 | * 4 | * @template T - This type parameter represents the type of the object that will be returned by the class constructor. 5 | * By default it is 'any', which means it can be any type of object. However, if you want more 6 | * control over the type that the constructor can return, you can provide a specific type by using `ClassConstructor`. 7 | * 8 | * @param {...any[]} args - This represents any number of arguments that the class constructor can accept. 9 | * Since this is an 'any[]' type, the arguments can be of any type and in any number. 10 | * 11 | * @returns {T} - The return type is `T`, which is the same type that was provided to the type parameter when using `ClassConstructor`. 12 | * In other words, the class constructor will return an object of type `T`. 13 | * 14 | * @example 15 | * // To use it with a specific type: 16 | * type MyClassConstructor = ClassConstructor; 17 | * const myClassInstance: MyClass = new MyClassConstructor(args); 18 | * 19 | * // To use it with any type: 20 | * type AnyClassConstructor = ClassConstructor; 21 | * const anyClassInstance: any = new AnyClassConstructor(args); 22 | */ 23 | 24 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 25 | export type ClassConstructor = new (...args: any[]) => T; 26 | -------------------------------------------------------------------------------- /src/ClassUtils/ClassInstance/ClassInstance.test.ts: -------------------------------------------------------------------------------- 1 | // @typescript-eslint/no-explicit-any - disable explicit any 2 | import { ClassInstance } from "./"; 3 | import { expectType } from "tsd"; 4 | 5 | class MiClase { 6 | constructor(public mensaje: string) {} 7 | } 8 | 9 | describe("[Test] ClassInstance", () => { 10 | it("returns a class instance", () => { 11 | const crearInstancia = any>(Clase: T, args: ConstructorParameters): ClassInstance => { 12 | return new Clase(...args) as ClassInstance; 13 | }; 14 | 15 | const instancia = crearInstancia(MiClase, ["Hola Mundo"]); 16 | 17 | expectType(instancia); 18 | expect(instancia).toBeInstanceOf(MiClase); 19 | expect(instancia.mensaje).toBe("Hola Mundo"); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/ClassUtils/ClassInstance/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ClassInstance is a utility type that gets the type of an instance of a given class. 3 | * This type is useful when you have a reference to a class (constructor) and you want to get the type of an instance of that class. 4 | * 5 | * @template T - This type parameter represents the class (constructor) from which you want to get the instance type. 6 | * 7 | * @returns {ClassInstance} - The return type is the type of an instance of the provided class. 8 | * If T cannot be resolved to an instance type (e.g., if T is not a constructor), then the return type will be 'any'. 9 | * 10 | * @example 11 | * // For use with a specific class: 12 | * class MyClass { 13 | * prop: number; 14 | * } 15 | * type MyClassInstance = ClassInstance; 16 | * const instance: MyClassInstance = new MyClass(); 17 | * 18 | * @note Note that ClassInstance cannot guarantee the type at runtime. 19 | * If you need to check the type at runtime, you will need to perform that check explicitly in your code. 20 | */ 21 | export type ClassInstance = T extends new (...args: any[]) => infer R ? R : any 22 | -------------------------------------------------------------------------------- /src/ClassUtils/MethodReturnType/MethodReturnType.test.ts: -------------------------------------------------------------------------------- 1 | import { MethodReturnType } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | class MyClass { 5 | greet(name: string): string { 6 | return `Hello, ${name}!`; 7 | } 8 | } 9 | 10 | describe("[Test] MethodReturnType", () => { 11 | it("returns the return type of a method", () => { 12 | const myInstance = new MyClass(); 13 | 14 | const result = myInstance.greet("John"); 15 | 16 | // Esperamos que el tipo del resultado sea el tipo de retorno del método greet 17 | expectType>(result); 18 | expect(result).toBe("Hello, John!"); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /src/ClassUtils/MethodReturnType/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * MethodReturnType is a utility type that gets the return type of a specific method within a `T` object. 3 | * It is useful when you want to work with the return type of a specific method within an object. 4 | * 5 | * @template T - This type parameter represents the object you are interested in. 6 | * 7 | * @template K - This type parameter represents the key of the method within the `T` object whose return type you are interested in obtaining. 8 | * 9 | * @returns {MethodReturnType} - The return type is the return type of the method that corresponds to the `K` key within the `T` object. 10 | * If the key `K` does not correspond to a method in `T`, or if the method does not have an explicit return type, the return type will be `any`. 11 | * 12 | * @example 13 | * // For use with a specific object and method key: 14 | * class MyClass { 15 | * myMethod(): number { return 42; } 16 | * } 17 | * 18 | * type MyMethodReturnType = MethodReturnType; // number. 19 | * 20 | * @note MethodReturnType can be useful for working with the return type of specific methods. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at run-time. 21 | */ 22 | export type MethodReturnType = T[K] extends (...args: any[]) => infer R ? R : any; 23 | -------------------------------------------------------------------------------- /src/ClassUtils/PublicMethods/PublicMethods.test.ts: -------------------------------------------------------------------------------- 1 | import { PublicMethods } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | class MiClase { 5 | public nombre: string = "Juan"; 6 | public apellido: string = "Perez"; 7 | 8 | public saludar() { 9 | return `Hola, mi nombre es ${this.nombre} ${this.apellido}`; 10 | } 11 | } 12 | 13 | describe("[Test] PublicMethods", () => { 14 | it("returns the public methods of a class", () => { 15 | const obtenerMetodosPublicos = (obj: T): Array> => { 16 | const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).filter( 17 | key => typeof obj[key] === "function" && key !== "constructor" 18 | ) as Array>; 19 | return keys; 20 | }; 21 | 22 | const miObjeto = new MiClase(); 23 | 24 | const resultado = obtenerMetodosPublicos(miObjeto); 25 | 26 | expectType>>(resultado); 27 | expect(resultado).toEqual(["saludar"]); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/ClassUtils/PublicMethods/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * PublicMethods is a utility type that gets all the keys of a `T` object that correspond to public methods. 3 | * It is useful when you want to work with the keys of an object that represent public methods. 4 | * 5 | * @template T - This type parameter represents the object you are interested in. 6 | * 7 | * @returns {PublicMethods} - The return type is a union type of all keys in `T` that correspond to public methods. 8 | * If there are no keys that are public methods, the return type will be `never`. 9 | * 10 | * @example 11 | * // For use with a specific object: 12 | * class MyClass { 13 | * public myPublicMethod(): void { } 14 | * private myPrivateMethod(): void { } 15 | * } 16 | * 17 | * type MyPublicMethods = PublicMethods; // "myPublicMethod". 18 | * 19 | * @note PublicMethods can be useful for working with object keys representing public methods. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. 20 | */ 21 | export type PublicMethods = { 22 | [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never; 23 | }[keyof T]; 24 | -------------------------------------------------------------------------------- /src/ClassUtils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ClassConstructor/"; 2 | export * from "./ClassInstance/"; 3 | -------------------------------------------------------------------------------- /src/InterfaceUtils/DeepReadOnly/DeepReadOnly.test.ts: -------------------------------------------------------------------------------- 1 | import { DeepReadonly } from "./"; 2 | import { ExampleObjectOne } from "./../../../test/utils/ExampleObjectData"; 3 | 4 | describe("[Test] DeepReadonly", () => { 5 | it("no permite modificar los datos", () => { 6 | 7 | function transformarAReadonly(): DeepReadonly { 8 | return ExampleObjectOne; 9 | } 10 | const datosReadonly = transformarAReadonly(); 11 | 12 | expect(datosReadonly.user.name).toEqual("John Doe"); 13 | expect(datosReadonly.user.details.age).toEqual(30); 14 | expect(datosReadonly.user.details.address.street).toEqual("street 123"); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/InterfaceUtils/DeepReadOnly/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * DeepReadonly is a utility type in TypeScript that takes a `T` type and makes all of its properties (and the properties of its properties, etc.) read-only. 3 | * 4 | * @template T - This type parameter represents any type of object you wish to convert to a read-only version. 5 | * 6 | * @returns {DeepReadonly} - The return type is a "deep" read-only version of `T`. 7 | * Each property of `T` (and subproperties, etc.) will be read-only, which means that you cannot assign new values to them after creation. 8 | * 9 | * @example 10 | * // For use with a single object: 11 | * type MyReadonlyObj = DeepReadonly<{ prop: number, subObj: { prop2: string } }>; 12 | * const obj: MyReadonlyObj = { prop: 1, subObj: { prop2: 'test' } }; 13 | * // This will give an error, since 'prop' is read-only. 14 | * obj.prop = 2; 15 | * 16 | * @note DeepReadonly can be very useful for working with complex object types and ensuring immutability, but be aware that it can have a performance impact if overused. 17 | */ 18 | export type DeepReadonly = { 19 | readonly [P in keyof T]: T[P] extends object ? DeepReadonly : T[P]; 20 | }; 21 | -------------------------------------------------------------------------------- /src/InterfaceUtils/KeysOfType/KeysOfType.test.ts: -------------------------------------------------------------------------------- 1 | import { KeysOfType } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | interface IMiInterfaz { 5 | nombre: string; 6 | edad: number; 7 | direccion: string; 8 | activo: boolean; 9 | } 10 | 11 | describe("[Test] KeysOfType", () => { 12 | it("returns keys of a specific type", () => { 13 | const getKeysOfString = (obj: T): Array> => { 14 | const keys = (Object.keys(obj) as Array).filter( 15 | key => typeof obj[key] === "string" 16 | ) as Array>; 17 | return keys; 18 | }; 19 | 20 | const miObjeto: IMiInterfaz = { nombre: "Juan", edad: 30, direccion: "Calle Falsa 123", activo: true }; 21 | 22 | const resultado = getKeysOfString(miObjeto); 23 | 24 | expectType>>(resultado); 25 | expect(resultado).toEqual(["nombre", "direccion"]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/InterfaceUtils/KeysOfType/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * KeysOfType is a utility type that gets all the keys of a `T` object whose values correspond to the `U` type. 3 | * It is useful when you want to work with keys of an object that have a specific value type. 4 | * 5 | * @template T - This type parameter represents the object you are interested in. 6 | * 7 | * @template U - This type parameter represents the type of value you are looking for within the `T` object. 8 | * 9 | * @returns {KeysOfType} - The return type is a union type of all keys in `T` whose values correspond to type `U`. 10 | * If there are no keys having a value of type `U`, the return type will be `never`. 11 | * 12 | * @example 13 | * // For use with a specific object and value type: 14 | * type MyType = { a: number; b: string; c: number; }; 15 | * type NumberKeys = KeysOfType; // 'a' | 'c' 16 | * 17 | * @note KeysOfType can be useful for working with object keys that have a specific type value. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at run-time. 18 | */ 19 | export type KeysOfType = { 20 | [K in keyof T]: T[K] extends U ? K : never; 21 | }[keyof T]; 22 | -------------------------------------------------------------------------------- /src/InterfaceUtils/OmitByValueType/OmitByValueType.test.ts: -------------------------------------------------------------------------------- 1 | import { OmitByValueType } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | interface IMiInterfaz { 5 | nombre: string; 6 | edad: number; 7 | direccion: string; 8 | activo: boolean; 9 | } 10 | 11 | describe("[Test] OmitByValueType", () => { 12 | it("returns keys not of a specific type", () => { 13 | const getNonStringKeys = (obj: T): Array> => { 14 | const keys = (Object.keys(obj) as Array).filter( 15 | key => typeof obj[key] !== "string" 16 | ) as Array>; 17 | return keys; 18 | }; 19 | 20 | const miObjeto: IMiInterfaz = { nombre: "Juan", edad: 30, direccion: "Calle Falsa 123", activo: true }; 21 | 22 | const resultado = getNonStringKeys(miObjeto); 23 | 24 | // Esperamos que el resultado sea de tipo Array> 25 | expectType>>(resultado); 26 | expect(resultado).toEqual(["edad", "activo"]); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/InterfaceUtils/OmitByValueType/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * OmitByValueType is a utility type that gets all keys of a `T` object whose values do not correspond to the `U` type. 3 | * It is useful when you want to work with keys of an object that have a specific value type and exclude those that do not. 4 | * 5 | * @template T - This type parameter represents the object you are interested in. 6 | * 7 | * @template U - This type parameter represents the type of value you are looking to exclude within the `T` object. 8 | * 9 | * @returns {OmitByValueType} - The return type is a union type of all keys in `T` whose values do not correspond to type `U`. 10 | * If all keys have a value of type `U`, the return type will be `never`. 11 | * 12 | * @example 13 | * // For use with a specific object and value type: 14 | * type MyType = { a: number; b: string; c: number; }; 15 | * type NonNumberKeys = OmitByValueType; // 'b' 16 | * 17 | * @note OmitByValueType can be useful for working with object keys that have a specific value type. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. 18 | */ 19 | export type OmitByValueType = { 20 | [P in keyof T]: T[P] extends U ? never : P; 21 | }[keyof T]; 22 | -------------------------------------------------------------------------------- /src/InterfaceUtils/OverrideInterface/OverrideInterface.test.ts: -------------------------------------------------------------------------------- 1 | import { OverrideInterface } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | interface IFuente { 5 | nombre: string; 6 | edad: number; 7 | direccion: string; 8 | } 9 | 10 | interface IOverride { 11 | nombre: string; 12 | ciudad: string; 13 | } 14 | 15 | describe("[Test] OverrideInterface", () => { 16 | it("overrides properties from the source interface", () => { 17 | const getDatos = (fuente: T, override: U): OverrideInterface => { 18 | return { ...fuente, ...override }; 19 | }; 20 | 21 | const fuente: IFuente = { nombre: "Juan", edad: 30, direccion: "Calle Falsa 123" }; 22 | const override: IOverride = { nombre: "Pedro", ciudad: "Madrid" }; 23 | 24 | const resultado = getDatos(fuente, override); 25 | 26 | expectType>(resultado); 27 | expect(resultado).toEqual({ nombre: "Pedro", edad: 30, direccion: "Calle Falsa 123", ciudad: "Madrid" }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/InterfaceUtils/OverrideInterface/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * OverrideInterface is a utility type that takes two types `T` and `U`, and combines their properties. 3 | * However, if `T` and `U` have properties with the same keys, the properties of `U` overwrite those of `T`. 4 | * 5 | * @template T - This type parameter represents the first type you want to combine. 6 | * 7 | * @template U - This type parameter represents the second type, whose properties will overwrite those of `T` if they have the same keys. 8 | * 9 | * @returns {OverrideInterface} - The return type is a combination of `T` and `U`, but with the properties of `U` overwriting those of `T` if they have the same keys. 10 | * 11 | * @example 12 | * // For use with two specific interface types: 13 | * interface MyFirstType { a: number; b: string; } 14 | * interface MySecondType { b: number; c: boolean; } 15 | * type MyOverrideType = OverrideInterface; 16 | * // The resulting type is { a: number; b: number; c: boolean; } 17 | * 18 | * @note OverrideInterface can be useful for modifying existing types or for combining types with possibly matching properties. Note, however, that TypeScript is a compile-time type system and cannot guarantee run-time consistency. 19 | */ 20 | export type OverrideInterface = Omit & U; 21 | -------------------------------------------------------------------------------- /src/InterfaceUtils/ReadonlyKeys/ReadonlyKeys.test.ts: -------------------------------------------------------------------------------- 1 | import { ReadonlyKeys } from "."; 2 | import { expectType } from "tsd"; 3 | type MyObject = { 4 | readonly myReadonlyProperty: number; 5 | myWritableProperty: string; 6 | }; 7 | 8 | describe("[Test] ReadonlyKeys", () => { 9 | it("returns the keys of readonly properties", () => { 10 | type MyReadonlyKeys = ReadonlyKeys; 11 | 12 | expectType<"myReadonlyProperty">(null as MyReadonlyKeys); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/InterfaceUtils/ReadonlyKeys/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ReadonlyKeys is a utility type in TypeScript that retrieves all keys of an object `T` that represent readonly properties. 3 | * It's helpful when you want to work with keys of an object representing properties that cannot be altered (are readonly). 4 | * 5 | * @template T - This type parameter represents the object from which you're interested in obtaining the keys of readonly properties. 6 | * 7 | * @returns {ReadonlyKeys} - The return type is a union type of all keys in `T` that correspond to readonly properties. 8 | * If there are no keys that are readonly properties, the return type will be 'never'. 9 | * 10 | * @example 11 | * // To use it with a specific object: 12 | * type MyObject = { 13 | * readonly myReadonlyProperty: number; 14 | * myWritableProperty: string; 15 | * }; 16 | * 17 | * type MyReadonlyKeys = ReadonlyKeys; // "myReadonlyProperty" 18 | * 19 | * @note ReadonlyKeys can be useful when working with keys of objects representing readonly properties. 20 | * However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. 21 | */ 22 | export type ReadonlyKeys = { [P in keyof T]: T extends ReadonlyArray ? P : never }[keyof T]; 23 | -------------------------------------------------------------------------------- /src/InterfaceUtils/RequireAtLeastOne/RequireAtLeastOne.test.ts: -------------------------------------------------------------------------------- 1 | import { RequireAtLeastOne } from "."; 2 | import { expectType } from "tsd"; 3 | interface MyInterface { 4 | prop1?: number; 5 | prop2?: string; 6 | prop3?: boolean; 7 | } 8 | 9 | describe("[Test] RequireAtLeastOne", () => { 10 | it("requires at least one property from the specified keys", () => { 11 | const obj1: RequireAtLeastOne = { 12 | prop1: 123, 13 | }; 14 | 15 | const obj2: RequireAtLeastOne = { 16 | prop2: "hello", 17 | }; 18 | 19 | const obj3: RequireAtLeastOne = { 20 | prop1: 123, 21 | prop2: "hello", 22 | }; 23 | expectType(obj1); 24 | expectType(obj2); 25 | expectType(obj3); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/InterfaceUtils/RequireAtLeastOne/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * RequireAtLeastOne is a utility type that enforces that at least one of the properties of an object `T` should be present. 3 | * The type parameter `Keys` represents the keys that you're interested in. If it's not explicitly provided, it defaults to `keyof T`, 4 | * meaning it will consider all keys in `T`. 5 | * 6 | * @template T - This type parameter represents the object that you're interested in. 7 | * 8 | * @template Keys - This type parameter represents the keys of `T` that should have at least one defined. 9 | * 10 | * @returns {RequireAtLeastOne} - The return type is an object type that enforces that at least one of the specified keys should be present in the object. 11 | * 12 | * @example 13 | * // To use it with a specific object type and keys: 14 | * type MyObject = { 15 | * prop1?: number; 16 | * prop2?: string; 17 | * prop3?: boolean; 18 | * }; 19 | * 20 | * type MyObjectWithAtLeastOne = RequireAtLeastOne; 21 | * // An object of this type must have either 'prop1' or 'prop2', or both. 22 | * 23 | * @note RequireAtLeastOne can be useful when you want to enforce that at least one of certain properties must be present in an object. 24 | * However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. 25 | */ 26 | export type RequireAtLeastOne = 27 | Pick> 28 | & { 29 | [K in Keys]-?: Required> & Partial>> 30 | }[Keys] 31 | -------------------------------------------------------------------------------- /src/InterfaceUtils/UnionToIntersection/UnionToIntersection.test.ts: -------------------------------------------------------------------------------- 1 | import { UnionToIntersection } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | describe("[Test] UnionToIntersection", () => { 5 | it("converts a union type to an intersection type", () => { 6 | type MiUnion = { nombre: string } | { apellido: string }; 7 | 8 | const mergeObjects = (...objs: T): UnionToIntersection => { 9 | return objs.reduce((acc, obj) => ({ ...acc, ...obj }), {} as any); 10 | }; 11 | 12 | const miObjeto1 = { nombre: "Juan" }; 13 | const miObjeto2 = { apellido: "Perez" }; 14 | const resultado = mergeObjects(miObjeto1, miObjeto2); 15 | 16 | // Esperamos que el resultado sea de tipo UnionToIntersection 17 | expectType>(resultado); 18 | expect(resultado).toEqual({ nombre: "Juan", apellido: "Perez" }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /src/InterfaceUtils/UnionToIntersection/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * UnionToIntersection is a utility type that takes a union of types and converts them into an intersection of types. 3 | * It is useful when you have a union of types and need to work with a type that includes all the properties of each type in the union. 4 | * 5 | * @template U - This type parameter represents the union of types you want to convert to an intersection. 6 | * 7 | * @returns {UnionToIntersection} - The return type is an intersection of all types in the union `U`. 8 | * If `U` is not a union of types, the return type will be `U` unchanged. 9 | * 10 | * @example 11 | * // To use with a union of types: 12 | * type MyUnion = { a: number; } | { b: string; }; 13 | * type MyIntersection = UnionToIntersection; // { a: number; } & { { b: string; } 14 | * 15 | * @note UnionToIntersection can be useful for working with type intersections from type unions. However, remember that TypeScript is a compile-time type system and cannot guarantee type consistency at runtime. 16 | */ 17 | export type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; 18 | -------------------------------------------------------------------------------- /src/InterfaceUtils/WritableKeys/WritableKeys.test.ts: -------------------------------------------------------------------------------- 1 | import { WritableKeys } from "."; 2 | import { expectType } from "tsd"; 3 | 4 | describe("[Test] WritableKeys", () => { 5 | it("returns the writable keys of a given object", () => { 6 | 7 | type MiObjeto = { 8 | readonly soloLectura: string; 9 | escritura: number; 10 | otroEscritura: boolean; 11 | }; 12 | 13 | // Esperamos que los tipos sean los correctos. 14 | expectType<"escritura" | "otroEscritura">(null as any as WritableKeys); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/InterfaceUtils/WritableKeys/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * WritableKeys is a utility type that retrieves all keys of an object `T` that represent writable properties (i.e., not read-only). 3 | * It's useful when you want to work with keys of an object representing properties that can be altered. 4 | * 5 | * @template T - This type parameter represents the object from which you're interested in obtaining the keys of writable properties. 6 | * 7 | * @returns {WritableKeys} - The return type is a union type of all keys in `T` that correspond to writable properties. 8 | * If there are no keys that are writable properties, the return type will be 'never'. 9 | * 10 | * @example 11 | * // To use it with a specific object: 12 | * type MyObject = { 13 | * readonly myReadonlyProperty: number; 14 | * myWritableProperty: string; 15 | * }; 16 | * 17 | * type MyWritableKeys = WritableKeys; // "myWritableProperty" 18 | * 19 | * @note WritableKeys can be useful when working with keys of objects representing writable properties. However, remember that TypeScript is a compile-time type system and cannot guarantee type safety at runtime. 20 | */ 21 | export type WritableKeys = { 22 | [P in keyof T]: ReadonlyArray extends ReadonlyArray ? never : P; 23 | }[keyof T]; 24 | -------------------------------------------------------------------------------- /src/InterfaceUtils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./DeepReadOnly"; 2 | export * from "./OverrideInterface"; 3 | export * from "./KeysOfType"; 4 | -------------------------------------------------------------------------------- /test/utils/ExampleObjectData.ts: -------------------------------------------------------------------------------- 1 | export const ExampleObjectOne = { 2 | user: { 3 | name: "John Doe", 4 | details: { 5 | age: 30, 6 | address: { 7 | street: "street 123", 8 | city: "city X" 9 | } 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/utils/UsuarioClass.ts: -------------------------------------------------------------------------------- 1 | export class Usuario { 2 | constructor(public nombre: string, public edad: number) {} 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./lib", 7 | "esModuleInterop": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictFunctionTypes": true, 12 | "skipLibCheck": true 13 | }, 14 | "include": ["src/**/*", "index.ts"], 15 | "exclude": ["node_modules", "./**/*.test.ts",] 16 | } 17 | --------------------------------------------------------------------------------