@grimoire-cc/cli 0.4.1 → 0.5.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.
@@ -0,0 +1,373 @@
1
+ # Modern Features Guide — TypeScript 5.0 to 5.9
2
+
3
+ ## Table of Contents
4
+
5
+ - [TypeScript 5.0](#typescript-50)
6
+ - [TypeScript 5.1](#typescript-51)
7
+ - [TypeScript 5.2](#typescript-52)
8
+ - [TypeScript 5.3](#typescript-53)
9
+ - [TypeScript 5.4](#typescript-54)
10
+ - [TypeScript 5.5](#typescript-55)
11
+ - [TypeScript 5.6](#typescript-56)
12
+ - [TypeScript 5.7](#typescript-57)
13
+ - [TypeScript 5.8](#typescript-58)
14
+ - [TypeScript 5.9](#typescript-59)
15
+ - [Looking Ahead: TypeScript 7](#looking-ahead-typescript-7)
16
+
17
+ ## TypeScript 5.0
18
+
19
+ ### Decorators (Stage 3 Standard)
20
+
21
+ TC39-compliant decorators replacing the experimental decorator implementation.
22
+
23
+ ```typescript
24
+ function logged(target: Function, context: ClassMethodDecoratorContext) {
25
+ const name = String(context.name);
26
+ return function (this: unknown, ...args: unknown[]) {
27
+ console.log(`Calling ${name}`);
28
+ return (target as Function).apply(this, args);
29
+ };
30
+ }
31
+
32
+ class UserService {
33
+ @logged
34
+ getUser(id: string): User { /* ... */ }
35
+ }
36
+ ```
37
+
38
+ ### `const` Type Parameters
39
+
40
+ Infer literal types from generic arguments without requiring `as const` at call sites.
41
+
42
+ ```typescript
43
+ function createRoutes<const T extends Record<string, string>>(routes: T): T {
44
+ return routes;
45
+ }
46
+
47
+ // Infers { readonly home: "/"; readonly about: "/about" }
48
+ const routes = createRoutes({ home: "/", about: "/about" });
49
+ ```
50
+
51
+ ### `satisfies` Operator
52
+
53
+ Validates that an expression matches a type without widening the inferred type.
54
+
55
+ ```typescript
56
+ type Color = "red" | "green" | "blue";
57
+ type ColorMap = Record<Color, string | [number, number, number]>;
58
+
59
+ const palette = {
60
+ red: [255, 0, 0],
61
+ green: "#00ff00",
62
+ blue: [0, 0, 255],
63
+ } satisfies ColorMap;
64
+
65
+ // palette.green is string (not string | number[])
66
+ palette.green.toUpperCase(); // OK
67
+ ```
68
+
69
+ ### Enum Improvements
70
+
71
+ All enums are now union enums, and enum members can be computed from other enum values.
72
+
73
+ ### `--moduleResolution bundler`
74
+
75
+ New module resolution mode for bundler-based workflows (Vite, esbuild, webpack).
76
+
77
+ ## TypeScript 5.1
78
+
79
+ ### Easier Implicit Returns for `undefined`
80
+
81
+ Functions returning `undefined` no longer need an explicit `return` statement.
82
+
83
+ ```typescript
84
+ function log(msg: string): undefined {
85
+ console.log(msg);
86
+ // No return needed
87
+ }
88
+ ```
89
+
90
+ ### Unlinked Type Predicates for Getters/Setters
91
+
92
+ Getters and setters can now have unrelated types.
93
+
94
+ ```typescript
95
+ class Box {
96
+ #value: unknown;
97
+
98
+ get value(): string {
99
+ return String(this.#value);
100
+ }
101
+
102
+ set value(newValue: string | number | boolean) {
103
+ this.#value = newValue;
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## TypeScript 5.2
109
+
110
+ ### `using` Declarations (Explicit Resource Management)
111
+
112
+ Deterministic cleanup of resources when they go out of scope.
113
+
114
+ ```typescript
115
+ class TempFile implements Disposable {
116
+ #path: string;
117
+
118
+ constructor(path: string) {
119
+ this.#path = path;
120
+ writeFileSync(path, "");
121
+ }
122
+
123
+ write(data: string): void {
124
+ appendFileSync(this.#path, data);
125
+ }
126
+
127
+ [Symbol.dispose](): void {
128
+ unlinkSync(this.#path);
129
+ }
130
+ }
131
+
132
+ function processTempData(): void {
133
+ using tmp = new TempFile("/tmp/work.dat");
134
+ tmp.write("data");
135
+ // tmp is automatically deleted when scope exits
136
+ }
137
+ ```
138
+
139
+ ### `await using` for Async Disposal
140
+
141
+ ```typescript
142
+ class DbConnection implements AsyncDisposable {
143
+ async [Symbol.asyncDispose](): Promise<void> {
144
+ await this.close();
145
+ }
146
+ }
147
+
148
+ async function query(): Promise<Result> {
149
+ await using conn = await pool.acquire();
150
+ return conn.execute("SELECT 1");
151
+ // Connection returned to pool automatically
152
+ }
153
+ ```
154
+
155
+ ### Decorator Metadata
156
+
157
+ Access metadata set by decorators via `Symbol.metadata`.
158
+
159
+ ## TypeScript 5.3
160
+
161
+ ### `import` Attributes
162
+
163
+ Support for import attributes (JSON modules, CSS modules).
164
+
165
+ ```typescript
166
+ import config from "./config.json" with { type: "json" };
167
+ ```
168
+
169
+ ### `switch (true)` Narrowing
170
+
171
+ TypeScript now narrows types within `switch (true)` patterns.
172
+
173
+ ```typescript
174
+ function describe(value: string | number | boolean): string {
175
+ switch (true) {
176
+ case typeof value === "string":
177
+ return value.toUpperCase(); // value is string
178
+ case typeof value === "number":
179
+ return value.toFixed(2); // value is number
180
+ default:
181
+ return String(value);
182
+ }
183
+ }
184
+ ```
185
+
186
+ ## TypeScript 5.4
187
+
188
+ ### `NoInfer<T>` Utility Type
189
+
190
+ Prevents a type parameter position from contributing to inference.
191
+
192
+ ```typescript
193
+ function createStreetLight<C extends string>(
194
+ colors: C[],
195
+ defaultColor: NoInfer<C>,
196
+ ): void { /* ... */ }
197
+
198
+ createStreetLight(["red", "yellow", "green"], "red"); // OK
199
+ createStreetLight(["red", "yellow", "green"], "blue"); // Error
200
+ ```
201
+
202
+ ### Preserved Narrowing in Closures
203
+
204
+ Variables narrowed in the containing scope remain narrowed inside closures when the variable isn't reassigned.
205
+
206
+ ```typescript
207
+ function process(value: string | null) {
208
+ if (value !== null) {
209
+ // value is narrowed to string
210
+ setTimeout(() => {
211
+ console.log(value.length); // Still narrowed in closure
212
+ }, 100);
213
+ }
214
+ }
215
+ ```
216
+
217
+ ### `Object.groupBy` and `Map.groupBy` Types
218
+
219
+ ```typescript
220
+ const grouped = Object.groupBy(users, (user) => user.role);
221
+ // Record<string, User[]>
222
+ ```
223
+
224
+ ## TypeScript 5.5
225
+
226
+ ### Inferred Type Predicates
227
+
228
+ TypeScript automatically infers type predicates for functions that narrow types.
229
+
230
+ ```typescript
231
+ // Before 5.5 — required explicit annotation
232
+ function isString(x: unknown): x is string {
233
+ return typeof x === "string";
234
+ }
235
+
236
+ // 5.5+ — inferred automatically
237
+ const strings = values.filter((v) => typeof v === "string");
238
+ // Correctly typed as string[]
239
+
240
+ const nonNull = items.filter((item) => item != null);
241
+ // Correctly typed as NonNullable<T>[]
242
+ ```
243
+
244
+ ### Regular Expression Checking
245
+
246
+ TypeScript validates regular expression syntax at compile time.
247
+
248
+ ```typescript
249
+ const re = /(?<=\d+)\s+/; // Validated at compile time
250
+ const bad = /(?<=/; // Error: unterminated regex
251
+ ```
252
+
253
+ ### Isolated Declarations
254
+
255
+ New `--isolatedDeclarations` flag ensures `.d.ts` files can be generated without type checking.
256
+
257
+ ## TypeScript 5.6
258
+
259
+ ### Disallowed Nullish and Truthy Checks
260
+
261
+ TypeScript errors on always-truthy or always-nullish checks to catch bugs.
262
+
263
+ ```typescript
264
+ function check(x: string) {
265
+ if (x) { /* OK — string can be falsy ("") */ }
266
+ }
267
+
268
+ function check2(x: () => boolean) {
269
+ // Error — function reference is always truthy
270
+ // Did you mean to call it? x()
271
+ if (x) { /* ... */ }
272
+ }
273
+ ```
274
+
275
+ ### `--noUncheckedSideEffectImports`
276
+
277
+ Verifies that side-effect imports (`import "./setup"`) actually resolve to existing files.
278
+
279
+ ### Iterator Helper Methods
280
+
281
+ Built-in support for iterator helpers like `.map()`, `.filter()`, `.take()` on iterators.
282
+
283
+ ```typescript
284
+ function* naturals() {
285
+ let n = 0;
286
+ while (true) yield n++;
287
+ }
288
+
289
+ const firstTenEvens = naturals()
290
+ .filter((n) => n % 2 === 0)
291
+ .take(10)
292
+ .toArray();
293
+ ```
294
+
295
+ ## TypeScript 5.7
296
+
297
+ ### Never-Initialized Variable Checks
298
+
299
+ Detects variables used before assignment even when accessed inside nested functions.
300
+
301
+ ```typescript
302
+ function example() {
303
+ let value: string;
304
+
305
+ function inner() {
306
+ console.log(value); // Error: used before assigned
307
+ }
308
+
309
+ inner();
310
+ value = "hello";
311
+ }
312
+ ```
313
+
314
+ ### `--target es2024`
315
+
316
+ Enables `Object.groupBy`, `Map.groupBy`, `Promise.withResolvers`, and enhanced `ArrayBuffer` / `SharedArrayBuffer` support.
317
+
318
+ ### `--rewriteRelativeImportExtensions`
319
+
320
+ Automatically rewrites `.ts` → `.js`, `.mts` → `.mjs`, `.cts` → `.cjs` in relative imports during compilation.
321
+
322
+ ### JSON Import Validation
323
+
324
+ Under `--module nodenext`, JSON imports require `with { type: "json" }` and only support default exports.
325
+
326
+ ```typescript
327
+ import config from "./config.json" with { type: "json" };
328
+ // config.setting — OK
329
+ ```
330
+
331
+ ### V8 Compile Caching
332
+
333
+ Leverages Node.js 22's `module.enableCompileCache()` for ~2.5x faster startup.
334
+
335
+ ## TypeScript 5.8
336
+
337
+ ### Granular Return Expression Checks
338
+
339
+ Each branch of a conditional return expression is independently checked against the declared return type.
340
+
341
+ ```typescript
342
+ function process(input: string): number {
343
+ // Each branch checked separately for return type compatibility
344
+ return input.length > 0
345
+ ? parseInt(input) // checked: number ← OK
346
+ : "default"; // checked: string ← Error!
347
+ }
348
+ ```
349
+
350
+ ### Performance Optimizations
351
+
352
+ Build and watch mode performance improvements for large codebases.
353
+
354
+ ## TypeScript 5.9
355
+
356
+ ### Clean Default Configuration
357
+
358
+ `tsc --init` generates sensible defaults: `"module": "nodenext"`, `"target": "esnext"`, and strict type-checking enabled out of the box.
359
+
360
+ ### Conditional Return Types (Refined)
361
+
362
+ Improved checking of functions with conditional return types based on parameter types.
363
+
364
+ ## Looking Ahead: TypeScript 7
365
+
366
+ Microsoft is rewriting the TypeScript compiler in Go (`tsgo`) for 8-10x performance improvements. Key points:
367
+
368
+ - **TypeScript 6.x** — Continues the JS-based compiler with deprecations and breaking changes to align with the native codebase
369
+ - **TypeScript 7.0** — First fully native release, targeting early 2026
370
+ - **Backwards compatible** — Same TypeScript language, dramatically faster tooling
371
+ - **`tsgo`** available for early testing now
372
+
373
+ The language features and best practices in this guide will continue to work unchanged in TypeScript 7.