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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/docs/assets/img/npm.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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](https://github.com/Bryan-Herrera-DEV/typescript-common-utils/)
23 | - [NPM](https://www.npmjs.com/package/typescript-dev-utils)
24 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/assets/img/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/README.md:
--------------------------------------------------------------------------------
1 |
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 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
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 | 
41 |
42 | ## Contributors
43 |
44 |
45 |
46 |