1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"> 5 6 <title>Effective TypeScript</title> 7 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 8 <link href="/css/bootstrap.min.css" rel="stylesheet"> 9 <link href="https://fonts.googleapis.com/css2?family=Khula:wght@600&family=Open+Sans:ital,wght@0,300;0,400;0,600;1,300;1,400;1,600&display=swap" rel="stylesheet"> 10 <link href="/css/customize.css" rel="stylesheet"> 11 <link href="/css/highlight.vs.css" rel="stylesheet"> 12 <link rel="icon" type="image/png" href="/images/icon.png"> 13 <meta name="description" content="Effective TypeScript: 83 Specific Ways to Improve Your TypeScript"> 14 <meta name="twitter:card" content="summary"> 15 <meta name="twitter:creator" content="@danvdk"> 16 <meta name="twitter:domain" content="effectivetypescript.com"> 17 <meta name="twitter:title" content="Effective TypeScript › 83 Specific Ways to Improve Your TypeScript"> 18 <meta name="twitter:description" content="Effective TypeScript: 83 Specific Ways to Improve Your TypeScript"> 19 <meta name="twitter:img:src" content="https://effectivetypescript.com/images/cover-2e.jpg"> 20 21 <meta property="og:title" content="Effective TypeScript › 83 Specific Ways to Improve Your TypeScript"> 22 <meta property="og:description" content="Effective TypeScript: 83 Specific Ways to Improve Your TypeScript"> 23 <meta property="og:image" content="https://effectivetypescript.com/images/cover-2e.jpg"> 24 <meta property="og:url" content="https://effectivetypescript.com/"> 25 26 <link href="https://effectivetypescript.com/atom.xml" type="application/atom+xml" rel="alternate" title="Effective TypeScript Atom Feed"> 27 <meta name="generator" content="Hexo 5.4.0"></head> 28 29<!-- Google tag (gtag.js) -->
vendor: 64 bytes, lines 29-30
29 30<script async src="https://www.googletagmanager.com/gtag/js?id=
30G-1NXE8EL9YT
vendor: 12 bytes, line 30
30"></script>
31<script> 32
vendor: 134 bytes, lines 32-36
32window.dataLayer = window.dataLayer || []; 33 function gtag(){dataLayer.push(arguments);} 34 gtag('js', new Date()); 35 36 gtag('config', '
36G-1NXE8EL9YT
vendor: 6 bytes, lines 36-37
36'); 37
37var trackOutboundLink = function(category, url, e) { 38 if (!window.google_tag_manager) { 39 console.log('blocked!'); 40 return true; // probably blocked 41 } 42 43 // No need to use event_callback if the link is opening in a new tab. 44 var newTab = e && (e.metaKey || (e.currentTarget && e.currentTarget.target === '_blank')); 45 gtag('event', 'click', { 46 'event_category': category, 47 'event_label': url, 48 'transport_type': 'beacon', 49 'event_callback': !newTab ? function() { 50 document.location = url; 51 } : undefined 52 }); 53 54 return newTab; 55 } 56</script>
56 57 58<body class="index"> 59 <div class="header"> 60 <div class="container"> 61 <div class="row"> 62 <div class="col-md-12"> 63 <h1 class="site-title"> 64 <a href="/"> 65 Effective TypeScript 66 </a> 67 </h1> 68 </div> 69 </div> 70 </div> 71</div> 72 73 <div class="container"> 74 <div class="row"> 75 <div class="col-md-12"> 76 <h2>All Effective TypeScript Posts</h2> 77 </div> 78 </div> 79 80 81 <div class="row"> 82 <div class="col-sm-12"> 83 <h4>2025</h4> 84 </div> 85 </div> 86 87 <div class="row all-posts-post"> 88 <div class="col-sm-2"> 89 2025-12-19 90 </div> 91 <div class="col-sm-10"> 92 <a href="/2025/12/19/ts-2025/">A Small Year for tsc, a Giant Year for TypeScript</a> 93 </div> 94 </div> 95 96 <div class="row all-posts-post"> 97 <div class="col-sm-2"> 98 2025-11-24 99 </div> 100 <div class="col-sm-10"> 101 <a href="/2025/11/24/advent2024-elixir/">What TypeScript & Elixir Can Learn from each Other (Advent of Code 2024)</a> 102 </div> 103 </div> 104 105 <div class="row"> 106 <div class="col-sm-12"> 107 <h4>2024</h4> 108 </div> 109 </div> 110 111 <div class="row all-posts-post"> 112 <div class="col-sm-2"> 113 2024-10-31 114 </div> 115 <div class="col-sm-10"> 116 <a href="/2024/10/31/runtime-types/">Item 74: Know How to Reconstruct Types at Runtime</a> 117 </div> 118 </div> 119 120 <div class="row all-posts-post"> 121 <div class="col-sm-2"> 122 2024-09-30 123 </div> 124 <div class="col-sm-10"> 125 <a href="/2024/09/30/ts-56/">Notes on TypeScript 5.6</a> 126 </div> 127 </div> 128 129 <div class="row all-posts-post"> 130 <div class="col-sm-2"> 131 2024-08-30 132 </div> 133 <div class="col-sm-10"> 134 <a href="/2024/08/30/keyof-puzzle/">A keyof puzzle</a> 135 </div> 136 </div> 137 138 <div class="row all-posts-post"> 139 <div class="col-sm-2"> 140 2024-07-17 141 </div> 142 <div class="col-sm-10"> 143 <a href="/2024/07/17/advent2023-zig/">A TypeScripter's Take on Zig (Advent of Code 2023)</a> 144 </div> 145 </div> 146 147 <div class="row all-posts-post"> 148 <div class="col-sm-2"> 149 2024-07-02 150 </div> 151 <div class="col-sm-10"> 152 <a href="/2024/07/02/ts-55/">TypeScript 5.5: A Blockbuster Release</a> 153 </div> 154 </div> 155 156 <div class="row all-posts-post"> 157 <div class="col-sm-2"> 158 2024-06-13 159 </div> 160 <div class="col-sm-10"> 161 <a href="/2024/06/13/special-values/">Item 36: Use a Distinct Type for Special Values</a> 162 </div> 163 </div> 164 165 <div class="row all-posts-post"> 166 <div class="col-sm-2"> 167 2024-05-21 168 </div> 169 <div class="col-sm-10"> 170 <a href="/2024/05/21/second-edition/">Now Available: Effective TypeScript, Second Edition</a> 171 </div> 172 </div> 173 174 <div class="row all-posts-post"> 175 <div class="col-sm-2"> 176 2024-04-16 177 </div> 178 <div class="col-sm-10"> 179 <a href="/2024/04/16/inferring-a-type-predicate/">The Making of a TypeScript Feature: Inferring Type Predicates</a> 180 </div> 181 </div> 182 183 <div class="row all-posts-post"> 184 <div class="col-sm-2"> 185 2024-03-24 186 </div> 187 <div class="col-sm-10"> 188 <a href="/2024/03/24/flownodes/">Flow Nodes: How Type Inference Is Implemented</a> 189 </div> 190 </div> 191 192 <div class="row all-posts-post"> 193 <div class="col-sm-2"> 194 2024-02-27 195 </div> 196 <div class="col-sm-10"> 197 <a href="/2024/02/27/type-guards/">The Hidden Side of Type Predicates</a> 198 </div> 199 </div> 200 201 <div class="row all-posts-post"> 202 <div class="col-sm-2"> 203 2024-01-31 204 </div> 205 <div class="col-sm-10"> 206 <a href="/2024/01/31/etsy/">Effective TypeScript Talk at Etsy (Dec 2020)</a> 207 </div> 208 </div> 209 210 <div class="row"> 211 <div class="col-sm-12"> 212 <h4>2023</h4> 213 </div> 214 </div> 215 216 <div class="row all-posts-post"> 217 <div class="col-sm-2"> 218 2023-12-31 219 </div> 220 <div class="col-sm-10"> 221 <a href="/2023/12/31/getters-setters/">Don't Write Traditional Getter and Setter Methods in JavaScript and TypeScript</a> 222 </div> 223 </div> 224 225 <div class="row all-posts-post"> 226 <div class="col-sm-2"> 227 2023-11-29 228 </div> 229 <div class="col-sm-10"> 230 <a href="/2023/11/29/infer-deep/">Using infer to unpack nested types</a> 231 </div> 232 </div> 233 234 <div class="row all-posts-post"> 235 <div class="col-sm-2"> 236 2023-10-27 237 </div> 238 <div class="col-sm-10"> 239 <a href="/2023/10/27/specialize-this/">Overload on the type of this to specialize generics (The Lost Item)</a> 240 </div> 241 </div> 242 243 <div class="row all-posts-post"> 244 <div class="col-sm-2"> 245 2023-09-27 246 </div> 247 <div class="col-sm-10"> 248 <a href="/2023/09/27/closure-compiler/">The Saga of the Closure Compiler, and Why TypeScript Won</a> 249 </div> 250 </div> 251 252 <div class="row all-posts-post"> 253 <div class="col-sm-2"> 254 2023-08-29 255 </div> 256 <div class="col-sm-10"> 257 <a href="/2023/08/29/sql/">TypeScript and SQL: Six Ways to Bridge the Divide</a> 258 </div> 259 </div> 260 261 <div class="row all-posts-post"> 262 <div class="col-sm-2"> 263 2023-07-29 264 </div> 265 <div class="col-sm-10"> 266 <a href="/2023/07/29/knip/">Recommendation Update: âï¸ Use knip to detect dead code and types</a> 267 </div> 268 </div> 269 270 <div class="row all-posts-post"> 271 <div class="col-sm-2"> 272 2023-06-27 273 </div> 274 <div class="col-sm-10"> 275 <a href="/2023/06/27/ts-51/">Notes on TypeScript 5.1</a> 276 </div> 277 </div> 278 279 <div class="row all-posts-post"> 280 <div class="col-sm-2"> 281 2023-05-31 282 </div> 283 <div class="col-sm-10"> 284 <a href="/2023/05/31/jsdoc-repeat/">Item 30: Donât Repeat Type Information in Documentation</a> 285 </div> 286 </div> 287 288 <div class="row all-posts-post"> 289 <div class="col-sm-2"> 290 2023-04-27 291 </div> 292 <div class="col-sm-10"> 293 <a href="/2023/04/27/aoc2022/">A first look at Deno through the Advent of Code 2022</a> 294 </div> 295 </div> 296 297 <div class="row all-posts-post"> 298 <div class="col-sm-2"> 299 2023-02-07 300 </div> 301 <div class="col-sm-10"> 302 <a href="/2023/02/07/ts-50-beta/">Notes on TypeScript 5.0 beta</a> 303 </div> 304 </div> 305 306 <div class="row"> 307 <div class="col-sm-12"> 308 <h4>2022</h4> 309 </div> 310 </div> 311 312 <div class="row all-posts-post"> 313 <div class="col-sm-2"> 314 2022-12-25 315 </div> 316 <div class="col-sm-10"> 317 <a href="/2022/12/25/christmas/">All I Want for Christmas Is⦠These Seven TypeScript Improvements</a> 318 </div> 319 </div> 320 321 <div class="row all-posts-post"> 322 <div class="col-sm-2"> 323 2022-07-30 324 </div> 325 <div class="col-sm-10"> 326 <a href="/2022/07/30/treemap-for-source-files/">What's TypeScript compiling? Use a treemap to find out.</a> 327 </div> 328 </div> 329 330 <div class="row all-posts-post"> 331 <div class="col-sm-2"> 332 2022-05-28 333 </div> 334 <div class="col-sm-10">
335 <a href="/2022/05/28/eslint-plugin-expect-type/">A new way to test types</a> 336 </div> 337 </div> 338 339 <div class="row all-posts-post"> 340 <div class="col-sm-2"> 341 2022-04-18 342 </div> 343 <div class="col-sm-10"> 344 <a href="/2022/04/18/twitch-expect-type/">My Twitch Debut (eslint-plugin-expect-type with Josh Goldberg)</a> 345 </div> 346 </div> 347 348 <div class="row all-posts-post"> 349 <div class="col-sm-2"> 350 2022-02-25 351 </div> 352 <div class="col-sm-10"> 353 <a href="/2022/02/25/gentips-4-display/">The display of types</a> 354 </div> 355 </div> 356 357 <div class="row all-posts-post"> 358 <div class="col-sm-2"> 359 2022-02-06 360 </div> 361 <div class="col-sm-10"> 362 <a href="/2022/02/06/advent-of-code-2021-golang/">A TypeScript Perspective on Go: the 2021 Advent of Code</a> 363 </div> 364 </div> 365 366 <div class="row"> 367 <div class="col-sm-12"> 368 <h4>2021</h4> 369 </div> 370 </div> 371 372 <div class="row all-posts-post"> 373 <div class="col-sm-2"> 374 2021-12-10 375 </div> 376 <div class="col-sm-10"> 377 <a href="/2021/12/10/typescript-types-the-first-500-years/">TypeScript Types: The First 500 Years (tsconf 2021 talk)</a> 378 </div> 379 </div> 380 381 <div class="row all-posts-post"> 382 <div class="col-sm-2"> 383 2021-11-11 384 </div> 385 <div class="col-sm-10"> 386 <a href="/2021/11/11/optional-never/">Exclusive Or and the Optional never Trick</a> 387 </div> 388 </div> 389 390 <div class="row all-posts-post"> 391 <div class="col-sm-2"> 392 2021-06-03 393 </div> 394 <div class="col-sm-10"> 395 <a href="/2021/06/03/interface/">In defense of interface: Using declaration merging to disable "bad parts"</a> 396 </div> 397 </div> 398 399 <div class="row all-posts-post"> 400 <div class="col-sm-2"> 401 2021-05-06 402 </div> 403 <div class="col-sm-10"> 404 <a href="/2021/05/06/unsoundness/">The Seven Sources of Unsoundness in TypeScript</a> 405 </div> 406 </div> 407 408 <div class="row all-posts-post"> 409 <div class="col-sm-2"> 410 2021-04-09 411 </div> 412 <div class="col-sm-10"> 413 <a href="/2021/04/09/unify-over-model/">The trouble with Jsonify: Unify types instead of modeling small differences</a> 414 </div> 415 </div> 416 417 <div class="row all-posts-post"> 418 <div class="col-sm-2"> 419 2021-03-24 420 </div> 421 <div class="col-sm-10"> 422 <a href="/2021/03/24/advent-of-code/">Advent of Code 2020, this time in Rust</a> 423 </div> 424 </div> 425 426 <div class="row all-posts-post"> 427 <div class="col-sm-2"> 428 2021-02-03 429 </div> 430 <div class="col-sm-10"> 431 <a href="/2021/02/03/pet-peeves/">Four words to avoid in TypeScript writing</a> 432 </div> 433 </div> 434 435 <div class="row all-posts-post"> 436 <div class="col-sm-2"> 437 2021-01-20 438 </div> 439 <div class="col-sm-10"> 440 <a href="/2021/01/20/gentips-3-aliases/">Generic Tips Part 3: Avoid Repeating Type Expressions</a> 441 </div> 442 </div> 443 444 <div class="row all-posts-post"> 445 <div class="col-sm-2"> 446 2021-01-09 447 </div> 448 <div class="col-sm-10"> 449 <a href="/2021/01/09/top-posts-2020/">Top Posts of 2020</a> 450 </div> 451 </div> 452 453 <div class="row"> 454 <div class="col-sm-12"> 455 <h4>2020</h4> 456 </div> 457 </div> 458 459 <div class="row all-posts-post"> 460 <div class="col-sm-2"> 461 2020-12-09 462 </div> 463 <div class="col-sm-10"> 464 <a href="/2020/12/09/gentips-2-intersect/">Generic Tips Part 2: Intersect what you have with whatever TypeScript wants</a> 465 </div> 466 </div> 467 468 <div class="row all-posts-post"> 469 <div class="col-sm-2"> 470 2020-12-04 471 </div> 472 <div class="col-sm-10"> 473 <a href="/2020/12/04/gentips-1-curry/">Generic Tips Part 1: Use Classes and Currying to create new inference sites</a> 474 </div> 475 </div> 476 477 <div class="row all-posts-post"> 478 <div class="col-sm-2"> 479 2020-11-05 480 </div> 481 <div class="col-sm-10"> 482 <a href="/2020/11/05/template-literal-types/">TypeScript Splits the Atom!</a> 483 </div> 484 </div> 485 486 <div class="row all-posts-post"> 487 <div class="col-sm-2"> 488 2020-10-20 489 </div> 490 <div class="col-sm-10"> 491 <a href="/2020/10/20/tsprune/">Finding dead code (and dead types) in TypeScript</a> 492 </div> 493 </div> 494 495 <div class="row all-posts-post"> 496 <div class="col-sm-2"> 497 2020-10-01 498 </div> 499 <div class="col-sm-10"> 500 <a href="/2020/10/01/prop-drilling/">Repeat yourself a little less: Strategies for mitigating prop drilling with React and TypeScript</a> 501 </div> 502 </div> 503 504 <div class="row all-posts-post"> 505 <div class="col-sm-2"> 506 2020-09-10 507 </div> 508 <div class="col-sm-10"> 509 <a href="/2020/09/10/problem-sets/">TypeScript Exercises</a> 510 </div> 511 </div> 512 513 <div class="row all-posts-post"> 514 <div class="col-sm-2"> 515 2020-08-12 516 </div> 517 <div class="col-sm-10"> 518 <a href="/2020/08/12/generics-golden-rule/">The Golden Rule of Generics</a> 519 </div> 520 </div> 521 522 <div class="row all-posts-post"> 523 <div class="col-sm-2"> 524 2020-07-27 525 </div> 526 <div class="col-sm-10"> 527 <a href="/2020/07/27/safe-queryselector/">Writing a safe querySelector: the one-way street from values to types</a> 528 </div> 529 </div> 530 531 <div class="row all-posts-post"> 532 <div class="col-sm-2"> 533 2020-06-30 534 </div> 535 <div class="col-sm-10"> 536 <a href="/2020/06/30/literate-ts/">Type-safe blogs and books with literate-ts</a> 537 </div> 538 </div> 539 540 <div class="row all-posts-post"> 541 <div class="col-sm-2"> 542 2020-06-16 543 </div> 544 <div class="col-sm-10"> 545 <a href="/2020/06/16/typed-identity-functions/">Use typed identity functions to guide type inference</a> 546 </div> 547 </div> 548 549 <div class="row all-posts-post"> 550 <div class="col-sm-2"> 551 2020-05-26 552 </div> 553 <div class="col-sm-10"> 554 <a href="/2020/05/26/iterate-objects/">Item 54: Know How to Iterate Over Objects</a> 555 </div> 556 </div> 557 558 <div class="row all-posts-post"> 559 <div class="col-sm-2"> 560 2020-05-12 561 </div> 562 <div class="col-sm-10"> 563 <a href="/2020/05/12/unionize-objectify/">Unionize and Objectify: A Trick for Applying Conditional Types to Objects</a> 564 </div> 565 </div> 566 567 <div class="row all-posts-post"> 568 <div class="col-sm-2"> 569 2020-04-28 570 </div> 571 <div class="col-sm-10"> 572 <a href="/2020/04/28/avoid-inferable/">Item 19: Avoid Cluttering Your Code with Inferable Types</a> 573 </div> 574 </div> 575 576 <div class="row all-posts-post"> 577 <div class="col-sm-2"> 578 2020-04-09 579 </div> 580 <div class="col-sm-10"> 581 <a href="/2020/04/09/jsonify/">What's the type of JSON.parse(âJSON.stringify(x))?</a> 582 </div> 583 </div> 584 585 <div class="row all-posts-post"> 586 <div class="col-sm-2"> 587 2020-03-24 588 </div> 589 <div class="col-sm-10"> 590 <a href="/2020/03/24/null-values-to-perimeter/">Item 31: Push Null Values to the Perimeter of Your Types</a> 591 </div> 592 </div> 593 594 <div class="row all-posts-post"> 595 <div class="col-sm-2"> 596 2020-03-09 597 </div> 598 <div class="col-sm-10"> 599 <a href="/2020/03/09/evolving-any/">Item 41: Understand Evolving any</a> 600 </div> 601 </div> 602 603 <div class="row all-posts-post"> 604 <div class="col-sm-2"> 605 2020-03-06 606 </div> 607 <div class="col-sm-10"> 608 <a href="/2020/03/06/hello-world/">Welcome to Effective TypeScript!</a> 609 </div> 610 </div> 611 612</div> 613 614 <footer id="contentinfo" class="footer"> 615 <div class="container"> 616 <address id="about" class="vcard body"> 617 © 2019 - 2025 <a class="url fn" target="_blank" rel="noopener" href="https://danvk.org" onclick="trackOutboundLink('footer', 'https://danvk.org'); return false;">Dan Vanderkam</a> 618 <div class="footer-attribution">Powered by <a href="https://hexo.io/" target="_blank" onclick="return trackOutboundLink('all effective typescript posts', 'https://hexo.io/', event);">Hexo</a></div>
619 </address> 620 </div> 621</footer> 622</body> 623</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.