├── .gitignore
├── README.md
├── build.ts
├── bun.lockb
├── img
└── tweet.png
├── package.json
├── src
└── index.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
2 |
3 | # Logs
4 |
5 | logs
6 | _.log
7 | npm-debug.log_
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 | .pnpm-debug.log*
12 |
13 | # Caches
14 |
15 | .cache
16 |
17 | # Diagnostic reports (https://nodejs.org/api/report.html)
18 |
19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
20 |
21 | # Runtime data
22 |
23 | pids
24 | _.pid
25 | _.seed
26 | *.pid.lock
27 |
28 | # Directory for instrumented libs generated by jscoverage/JSCover
29 |
30 | lib-cov
31 |
32 | # Coverage directory used by tools like istanbul
33 |
34 | coverage
35 | *.lcov
36 |
37 | # nyc test coverage
38 |
39 | .nyc_output
40 |
41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
42 |
43 | .grunt
44 |
45 | # Bower dependency directory (https://bower.io/)
46 |
47 | bower_components
48 |
49 | # node-waf configuration
50 |
51 | .lock-wscript
52 |
53 | # Compiled binary addons (https://nodejs.org/api/addons.html)
54 |
55 | build/Release
56 |
57 | # Dependency directories
58 |
59 | node_modules/
60 | jspm_packages/
61 |
62 | # Snowpack dependency directory (https://snowpack.dev/)
63 |
64 | web_modules/
65 |
66 | # TypeScript cache
67 |
68 | *.tsbuildinfo
69 |
70 | # Optional npm cache directory
71 |
72 | .npm
73 |
74 | # Optional eslint cache
75 |
76 | .eslintcache
77 |
78 | # Optional stylelint cache
79 |
80 | .stylelintcache
81 |
82 | # Microbundle cache
83 |
84 | .rpt2_cache/
85 | .rts2_cache_cjs/
86 | .rts2_cache_es/
87 | .rts2_cache_umd/
88 |
89 | # Optional REPL history
90 |
91 | .node_repl_history
92 |
93 | # Output of 'npm pack'
94 |
95 | *.tgz
96 |
97 | # Yarn Integrity file
98 |
99 | .yarn-integrity
100 |
101 | # dotenv environment variable files
102 |
103 | .env
104 | .env.development.local
105 | .env.test.local
106 | .env.production.local
107 | .env.local
108 |
109 | # parcel-bundler cache (https://parceljs.org/)
110 |
111 | .parcel-cache
112 |
113 | # Next.js build output
114 |
115 | .next
116 | out
117 |
118 | # Nuxt.js build / generate output
119 |
120 | .nuxt
121 | dist
122 |
123 | # Gatsby files
124 |
125 | # Comment in the public line in if your project uses Gatsby and not Next.js
126 |
127 | # https://nextjs.org/blog/next-9-1#public-directory-support
128 |
129 | # public
130 |
131 | # vuepress build output
132 |
133 | .vuepress/dist
134 |
135 | # vuepress v2.x temp and cache directory
136 |
137 | .temp
138 |
139 | # Docusaurus cache and generated files
140 |
141 | .docusaurus
142 |
143 | # Serverless directories
144 |
145 | .serverless/
146 |
147 | # FuseBox cache
148 |
149 | .fusebox/
150 |
151 | # DynamoDB Local files
152 |
153 | .dynamodb/
154 |
155 | # TernJS port file
156 |
157 | .tern-port
158 |
159 | # Stores VSCode versions used for testing VSCode extensions
160 |
161 | .vscode-test
162 |
163 | # yarn v2
164 |
165 | .yarn/cache
166 | .yarn/unplugged
167 | .yarn/build-state.yml
168 | .yarn/install-state.gz
169 | .pnp.*
170 |
171 | # IntelliJ based IDEs
172 | .idea
173 |
174 | # Finder (MacOS) folder config
175 | .DS_Store
176 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ts-init
2 |
3 | A CLI tool to initialize a tsconfig based on Matt Pocock's [tsconfig cheat sheet](https://www.totaltypescript.com/tsconfig-cheat-sheet).
4 |
5 | made cause of this tweet [here](https://x.com/mattpocockuk/status/1834839649593794566)
6 |
7 |
8 |
9 | ### Install
10 |
11 | ```bash
12 | npm install -g @bekacru/ts-init
13 | ```
14 |
15 | ### Usage
16 |
17 | ```bash
18 | npx ts-init
19 | ```
20 |
21 | ### License
22 |
23 | MIT
--------------------------------------------------------------------------------
/build.ts:
--------------------------------------------------------------------------------
1 | await Bun.build({
2 | entrypoints: ['./src/index.ts'],
3 | outdir: './dist',
4 | target: 'node',
5 | format: 'esm',
6 | external: ['commander', 'prompts'],
7 | minify: true,
8 | });
--------------------------------------------------------------------------------
/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bekacru/ts-init/99cd7eab279622406aee86c1a95ced8d634f3bc3/bun.lockb
--------------------------------------------------------------------------------
/img/tweet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bekacru/ts-init/99cd7eab279622406aee86c1a95ced8d634f3bc3/img/tweet.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bekacru/ts-init",
3 | "module": "dist/index.js",
4 | "version": "0.1.1",
5 | "main": "dist/index.js",
6 | "type": "module",
7 | "bin": "./dist/index.js",
8 | "scripts": {
9 | "dev": "bun run ./src/index.ts",
10 | "watch": "bun build ./src/index.ts --outdir=./dist --watch",
11 | "build": "bun run build.ts",
12 | "release": "bun run build && bumpp && npm publish --access public --no-git-checks"
13 | },
14 | "devDependencies": {
15 | "@types/bun": "latest",
16 | "@types/prompt": "^1.1.9",
17 | "bumpp": "^9.5.2",
18 | "@types/prompts": "^2.4.9",
19 | "typescript": "^5.0.0"
20 | },
21 | "dependencies": {
22 | "commander": "^12.1.0",
23 | "prompts": "^2.4.2"
24 | },
25 | "files": [
26 | "dist"
27 | ]
28 | }
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import { Command } from "commander";
3 | import prompt from "prompts";
4 | import fs from 'fs/promises';
5 | import path from 'path';
6 |
7 | const init = new Command()
8 | .name("")
9 | .description("Initialize a TypeScript project")
10 | .action(async () => {
11 | let options;
12 | try {
13 | options = await prompt([
14 | {
15 | type: "text",
16 | name: "projectName",
17 | message: "What is the name of your project?",
18 | initial: ".",
19 | },
20 | {
21 | type: "select",
22 | name: "strictness",
23 | message: "How strict should the typescript compiler be?",
24 | choices: [
25 | { title: "Relaxed (Few checks)", value: "off" },
26 | { title: "Balanced (Recommended)", value: "on" },
27 | { title: "Rigorous (Maximum safety)", value: "strict" },
28 | ],
29 | initial: 1,
30 | },
31 | {
32 | type: "confirm",
33 | name: "isTranspiler",
34 | message: "Are you transpiling using tsc?",
35 | initial: true,
36 | },
37 | {
38 | type: "confirm",
39 | name: "isLibrary",
40 | message: "Are you building a library?",
41 | initial: false,
42 | },
43 | {
44 | type: "confirm",
45 | name: "isMonorepo",
46 | message: "Are you building for a library in a monorepo?",
47 | initial: false,
48 | },
49 | {
50 | type: "confirm",
51 | name: "isDom",
52 | message: "Is your project for a dom (browser) environment?",
53 | initial: false,
54 | },
55 | ], {
56 | onCancel: () => {
57 | throw new Error('Operation cancelled');
58 | }
59 | });
60 | } catch (error) {
61 | console.log('Operation cancelled');
62 | process.exit(0);
63 | }
64 |
65 | if (!options || Object.keys(options).length === 0) {
66 | console.log('Operation cancelled');
67 | process.exit(0);
68 | }
69 |
70 | const projectDir = options.projectName === "." ? process.cwd() : path.join(process.cwd(), options.projectName);
71 |
72 | try {
73 | await fs.mkdir(projectDir, { recursive: true });
74 |
75 | const tsConfig = generateTsConfig(options);
76 | await fs.writeFile(path.join(projectDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
77 | console.log(`tsconfig.json has been generated in ${projectDir}`);
78 | } catch (error) {
79 | console.error('Error creating project files:', error);
80 | process.exit(1);
81 | }
82 | });
83 |
84 | function generateTsConfig(options: {
85 | strictness: "off" | "on" | "strict";
86 | isTranspiler: boolean;
87 | isLibrary: boolean;
88 | isMonorepo: boolean;
89 | isDom: boolean;
90 | }) {
91 | const config: { compilerOptions: Record } = {
92 | compilerOptions: {
93 | esModuleInterop: true,
94 | skipLibCheck: true,
95 | target: "es2022",
96 | allowJs: true,
97 | resolveJsonModule: true,
98 | moduleDetection: "force",
99 | isolatedModules: true,
100 | verbatimModuleSyntax: true,
101 | }
102 | };
103 |
104 | // Strictness
105 | if (options.strictness === "strict") {
106 | config.compilerOptions.strict = true;
107 | config.compilerOptions.noUncheckedIndexedAccess = true;
108 | config.compilerOptions.noImplicitOverride = true;
109 | } else if (options.strictness === "on") {
110 | config.compilerOptions.strict = true;
111 | }
112 |
113 | // Transpiling
114 | if (options.isTranspiler) {
115 | config.compilerOptions.module = "NodeNext";
116 | config.compilerOptions.outDir = "dist";
117 | config.compilerOptions.sourceMap = true;
118 | } else {
119 | config.compilerOptions.module = "preserve";
120 | config.compilerOptions.noEmit = true;
121 | }
122 |
123 | // Library
124 | if (options.isLibrary) {
125 | config.compilerOptions.declaration = true;
126 | }
127 |
128 | // Monorepo
129 | if (options.isMonorepo) {
130 | config.compilerOptions.composite = true;
131 | config.compilerOptions.declarationMap = true;
132 | }
133 |
134 | // DOM
135 | if (options.isDom) {
136 | config.compilerOptions.lib = ["es2022", "dom", "dom.iterable"];
137 | } else {
138 | config.compilerOptions.lib = ["es2022"];
139 | }
140 |
141 | return config;
142 | }
143 |
144 | function main() {
145 | init.parse(process.argv);
146 | }
147 |
148 | main();
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "esModuleInterop": true,
4 | "skipLibCheck": true,
5 | "target": "es2022",
6 | "allowJs": true,
7 | "resolveJsonModule": true,
8 | "moduleDetection": "force",
9 | "isolatedModules": true,
10 | "verbatimModuleSyntax": true,
11 | "strict": true,
12 | "noUncheckedIndexedAccess": true,
13 | "noImplicitOverride": true,
14 | "module": "preserve",
15 | "noEmit": true,
16 | "declaration": true,
17 | "lib": [
18 | "es2022"
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------