Effective TypeScript (2nd Edition) - Chinese Translation

website·Indexed 29 days ago

https://rayadaschn.github.io/effective-typeScript-2nd-edition-zh

A comprehensive guide to TypeScript best practices, featuring items on advanced type modeling (Template Literal Types, Optional Never Properties, Brands), compiler performance, and migration strategies from JavaScript. Covers topics such as exhaustiveness checking with never types, TSDoc for API comments, and the relationship between type checking and unit testing.

Tokens
67.7K
Snippets
303
Records
420
Agent score
73%

What's inside Effective TypeScript

  1. Use `unknown` instead of `any` for unknown values

    unknown is a type-safe alternative to any. Use unknown when you know a value exists but do not know or care about its specific type. Unlike any, which disables type checking by allowing any operation and assignment, unknown is a 'top type'—any type can be assigned to it, but it cannot be assigned to other types (except any or another unknown) without explicit type narrowing or assertions.
  2. Understand the three versions in TypeScript dependency management

    When managing dependencies in TypeScript, you must ensure synchronization between three distinct versions to avoid type errors or runtime crashes:

    1. Package Version: The version of the actual JavaScript library (e.g., react@18.2.0).
    2. Type Declaration Version (@types): The version of the type definitions (e.g., @types/react@18.2.23). The major and minor versions should match the package, while the patch version reflects fixes to the types themselves.
    3. TypeScript Version: The version of the TypeScript compiler used in your project. Type declarations often use the latest TS features and may require a minimum TS version to compile.

    Failure to sync these can lead to scenarios where code passes type checking but fails at runtime (types are newer than the library) or fails type checking despite the library supporting the feature (library is newer than the types).

  3. Understand TypeScript's structural typing system

    TypeScript uses a structural type system (similar to 'duck typing' in JavaScript). A value is considered compatible with a type if it contains all the required properties of that type, regardless of whether it contains additional properties or whether it was explicitly declared to implement a specific interface. Types are not 'closed'.
  4. Best practices for Type Annotations vs Assertions

    Follow these guidelines to maintain type safety in TypeScript:

    1. Prefer type annotations (: Type) over type assertions (as Type).
    2. Use type assertions or non-null assertions only when you are certain you have more information about the type than the TypeScript compiler does.
    3. When using a type assertion, include a comment explaining why the assertion is safe to prevent future regressions.
  5. Distinguish between Type Space and Value Space in TypeScript

    TypeScript symbols exist in two distinct spaces: Type Space and Value Space. Symbols in the type space are used for static type checking and are erased during compilation to JavaScript. Symbols in the value space exist at runtime.

    Key distinctions:

    • Type Space: Introduced by type and interface. These are erased at runtime.
    • Value Space: Introduced by const, let, var, or function implementations. These persist in the compiled JavaScript.
    • Dual Space: class and enum introduce both a type (based on the structure) and a value (the constructor function or the enum object).

    Context determines which space a symbol belongs to:

    • Symbols following a colon (:) or the as keyword are in the type space.
    • Symbols following an assignment operator (=) are in the value space.
    interface Person { // Type Space
      first: string
      last: string
    }
    
    const jane: Person = { first: 'Jane', last: 'Jacobs' }
    //    ^ Value Space  ^ Type Space  ^ Value Space
  6. Understand the relationship between TypeScript and JavaScript

    TypeScript is a syntactic superset of JavaScript. This means all valid JavaScript programs are also valid TypeScript programs, but not all TypeScript programs are valid JavaScript because TypeScript introduces additional syntax for type annotations. TypeScript provides a static type system that simulates JavaScript's runtime behavior to detect potential exceptions and bugs during compilation rather than at runtime.
  7. Understand the relationship between TypeScript and JavaScript

    TypeScript is a superset of JavaScript. This means all valid JavaScript programs are syntactically valid TypeScript programs. TypeScript adds a static type system that simulates JavaScript's runtime behavior to identify potential errors before the code is executed. While it allows many implicit JavaScript behaviors (like string concatenation with numbers), it prohibits certain legal but suspicious JavaScript patterns to prevent bugs.
  8. Understand the independence of TypeScript types and code generation

    The TypeScript compiler (tsc) performs two independent tasks: transpiling TypeScript/JavaScript to an older version of JavaScript and checking for type errors. Because these processes are decoupled, TypeScript types are 'erased' during compilation and do not exist at runtime. Consequently, type annotations do not affect the runtime behavior or performance of the generated JavaScript code. Notably, code with type errors can still be compiled into executable JavaScript output.