@alessiofrittoli/type-utils 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Type Utils ❇️
2
2
 
3
- Version 1.1.0
3
+ Version 1.3.0
4
4
 
5
5
  ## Lightweight TypeScript types utilities
6
6
 
@@ -41,21 +41,23 @@ pnpm i @alessiofrittoli/type-utils
41
41
  ```
42
42
 
43
43
  This tiny library defines some global types which are not imported in your IDE by default.\
44
- After installation a `postinstall` script is executed to create the `type-utils.d.ts` file at the root of your project.
45
- Please make sure to add it in the array of the "include" property in your `tsconfig.json`.
44
+ After installation a `postinstall` script is executed to create the `alessiofrittoli-env.d.ts` file at the root of your project.
45
+ This script will try to update your `tsconfig.json` file.
46
+
47
+ If that fail, please, make sure to add `alessiofrittoli-env.d.ts` in the array of the "include" property in your `tsconfig.json`.
46
48
 
47
49
  ```json
48
50
  {
49
51
  "compilerOptions": {
50
52
  ...
51
53
  },
52
- "include": [ ..., "type-utils.d.ts" ],
54
+ "include": [ ..., "alessiofrittoli-env.d.ts" ],
53
55
  }
54
56
  ```
55
57
 
56
58
  You can skip this process if `*.ts` is already in your "include" array.
57
59
 
58
- ⚠️ If the `type-utils.d.ts` file creation fails you run the following command to manually execute the script:
60
+ ⚠️ If the `alessiofrittoli-env.d.ts` file creation fails you can run the following command to manually execute the script:
59
61
 
60
62
  ```bash
61
63
  node node_modules/@alessiofrittoli/type-utils/scripts/postinstall/index.js
package/dist/index.d.mts CHANGED
@@ -60,6 +60,51 @@ declare global {
60
60
  type NonNullableFields<T> = {
61
61
  [P in keyof T]: NonNullable<T[P]>;
62
62
  };
63
+ /**
64
+ * Get the type of the value of merged enums.
65
+ *
66
+ * @example
67
+ *
68
+ * ```ts
69
+ * enum Mammals {
70
+ * Humans,
71
+ * Bats,
72
+ * Dolphins
73
+ * }
74
+ *
75
+ * enum Reptiles {
76
+ * Snakes,
77
+ * Alligators,
78
+ * Lizards
79
+ * }
80
+ *
81
+ * // merged enums.
82
+ * const Animals = { Mammals, Reptiles }
83
+ * type Animals = typeof Animals
84
+ *
85
+ * type Animal = MergedEnumValueType<typeof Animals>
86
+ *
87
+ * const testAnimal: Animal = 0 as any
88
+ *
89
+ * switch ( testAnimal ) {
90
+ * case Animals.Mammals.Humans:
91
+ * case Animals.Mammals.Bats:
92
+ * case Animals.Mammals.Dolphins:
93
+ * case Animals.Reptiles.Snakes:
94
+ * case Animals.Reptiles.Alligators:
95
+ * case Animals.Reptiles.Lizards:
96
+ * break
97
+ * default: {
98
+ * const invalid = testAnimal // `testAnimal` is type of never
99
+ * }
100
+ * }
101
+ * ```
102
+ */
103
+ type MergedEnumValue<T> = {
104
+ [K in keyof T]: {
105
+ [K2 in keyof T[K]]: T[K][K2];
106
+ }[keyof T[K]];
107
+ }[keyof T];
63
108
  }
64
109
 
65
110
  type DoNotUse = never;
package/dist/index.d.ts CHANGED
@@ -60,6 +60,51 @@ declare global {
60
60
  type NonNullableFields<T> = {
61
61
  [P in keyof T]: NonNullable<T[P]>;
62
62
  };
63
+ /**
64
+ * Get the type of the value of merged enums.
65
+ *
66
+ * @example
67
+ *
68
+ * ```ts
69
+ * enum Mammals {
70
+ * Humans,
71
+ * Bats,
72
+ * Dolphins
73
+ * }
74
+ *
75
+ * enum Reptiles {
76
+ * Snakes,
77
+ * Alligators,
78
+ * Lizards
79
+ * }
80
+ *
81
+ * // merged enums.
82
+ * const Animals = { Mammals, Reptiles }
83
+ * type Animals = typeof Animals
84
+ *
85
+ * type Animal = MergedEnumValueType<typeof Animals>
86
+ *
87
+ * const testAnimal: Animal = 0 as any
88
+ *
89
+ * switch ( testAnimal ) {
90
+ * case Animals.Mammals.Humans:
91
+ * case Animals.Mammals.Bats:
92
+ * case Animals.Mammals.Dolphins:
93
+ * case Animals.Reptiles.Snakes:
94
+ * case Animals.Reptiles.Alligators:
95
+ * case Animals.Reptiles.Lizards:
96
+ * break
97
+ * default: {
98
+ * const invalid = testAnimal // `testAnimal` is type of never
99
+ * }
100
+ * }
101
+ * ```
102
+ */
103
+ type MergedEnumValue<T> = {
104
+ [K in keyof T]: {
105
+ [K2 in keyof T[K]]: T[K][K2];
106
+ }[keyof T[K]];
107
+ }[keyof T];
63
108
  }
64
109
 
65
110
  type DoNotUse = never;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alessiofrittoli/type-utils",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Lightweight TypeScript types utilities",
5
5
  "author": {
6
6
  "name": "Alessio Frittoli",
@@ -23,10 +23,11 @@
23
23
  "main": "./dist/index.js",
24
24
  "types": "./dist/index.d.ts",
25
25
  "files": [
26
- "dist", "scripts"
26
+ "dist",
27
+ "scripts"
27
28
  ],
28
29
  "scripts": {
29
- "build": "eslint && tsup",
30
+ "build": "pnpm lint && tsup",
30
31
  "lint": "eslint",
31
32
  "postinstall": "node scripts/postinstall/index.js"
32
33
  },
@@ -38,5 +39,9 @@
38
39
  "tsup": "^8.3.5",
39
40
  "typescript": "^5.7.2",
40
41
  "typescript-eslint": "^8.18.1"
42
+ },
43
+ "dependencies": {
44
+ "@alessiofrittoli/chain-functions": "^1.0.1",
45
+ "@alessiofrittoli/post-install-scripts": "0.2.0"
41
46
  }
42
47
  }
@@ -1,12 +1,14 @@
1
- const tsSetup = require( './ts-setup.js' )
1
+ const Chain = require( '@alessiofrittoli/chain-functions' )
2
+ const tsSetup = require( './ts-setup.js' )
2
3
 
3
- /** @type {(() => void | Promise<void>)[]} */
4
- const scripts = [ tsSetup ]
5
-
6
- const executePostInstall = async () => {
7
- await Promise.all( scripts.map( async script => {
8
- await script()
9
- } ) )
4
+ /** @type {import( '@alessiofrittoli/chain-functions/types' ).LastChainLink<() => void | Promise<void>>} */
5
+ const lastChainLink = () => () => {
6
+ console.log( 'Post-install done.' )
10
7
  }
11
8
 
12
- executePostInstall()
9
+ /** @type {import( '@alessiofrittoli/chain-functions/types' ).ChainFactory<() => void | Promise<void>>} */
10
+ const chain = [ tsSetup, lastChainLink ]
11
+
12
+ ;( async () => {
13
+ await Chain.functions( chain )()
14
+ } )()
@@ -1,39 +1,17 @@
1
- const fs = require( 'fs' )
2
- const path = require( 'path' )
3
- const project = require( '../../package.json' )
1
+ const project = require( '../../package.json' )
2
+ const { addTypesReference } = require( '@alessiofrittoli/post-install-scripts' )
4
3
 
5
4
 
6
- const tsSetup = () => {
7
-
8
- const projectName = project.name.replace( '@alessiofrittoli/', '' )
9
- const projectRoot = process.env.INIT_CWD || process.cwd()
10
- const typesFilename = `${ projectName }.d.ts`
11
-
12
- if ( projectRoot.endsWith( projectName ) ) {
13
- console.log( `Skip "postinstall" script. Running in ${ project.name }` )
14
- return
15
- }
16
- if ( ! projectRoot ) {
17
- console.error( 'INIT_CWD is not set. This script must be run during pnpm install.' )
18
- process.exit( 1 )
19
- }
20
-
21
- const tsconfigPath = path.resolve( projectRoot, typesFilename )
22
-
23
- const data = [
24
- `/// <reference types="${ project.name }" />`,
25
- '// NOTE: This file should not be edited'
26
- ].join( '\n\n' )
27
-
28
- try {
29
- fs.writeFileSync( tsconfigPath, data )
30
- console.log( `"${ typesFilename }" has been created at the root of your project.` )
31
- console.log( 'Please update your tsconfig.json to add this file in your "include" property of your tsconfig.json file.' )
32
- } catch ( error ) {
33
- console.error( `An error occured while creating "${ typesFilename }" at the root of your project. Some global types may not working as expect.`, error )
34
- process.exit( 1 )
5
+ /** @type {import( '@alessiofrittoli/chain-functions/types' ).ChainLink<() => void | Promise<void>>} */
6
+ const tsSetup = next => () => {
7
+
8
+ /** @type {import( '@alessiofrittoli/post-install-scripts/types' ).AddTypesReferenceOptions} */
9
+ const options = {
10
+ projectName: project.name,
35
11
  }
12
+ addTypesReference( options )
36
13
 
14
+ return next()
37
15
  }
38
16
 
39
17
  module.exports = tsSetup