Skip to content
OVEX TECH
Education & E-Learning

Sharpen Your Code: Advanced TypeScript Configurations

Sharpen Your Code: Advanced TypeScript Configurations

Boost Your TypeScript Code Quality with These Configurations

Many developers believe that simply turning on strict mode in TypeScript is enough to catch all errors. However, even with strict mode enabled, code can still contain type errors that go unnoticed. This article will guide you through over 15 powerful TypeScript configurations that go beyond basic strict mode. You’ll learn how to set up your `tsconfig.json` file to catch a wider range of potential issues, leading to cleaner, more robust code.

What You’ll Learn

This guide will show you how to enhance your TypeScript project with advanced configurations. We’ll cover settings that help prevent typos, manage imports, ensure cleaner code, and even catch subtle errors in JavaScript interop. These options are often overlooked but are crucial for writing high-quality TypeScript.

Prerequisites

  • Basic understanding of TypeScript and its syntax.
  • A TypeScript project with a `tsconfig.json` file.
  • Familiarity with enabling `strict` mode in `tsconfig.json`.

Configuring `tsconfig.json` for Better Type Safety

1. Use Path Aliases for Cleaner Imports

Path aliases allow you to define custom shortcuts for your import paths. This makes your import statements cleaner and easier to manage, especially when dealing with deeply nested files. Instead of using long relative paths like ../../../../components/Button, you can use a shorter alias like @/components/Button.

  1. Open your tsconfig.json file.
  2. Add the compilerOptions.paths setting.
  3. Define your alias. A common practice is to use an ‘@/’ alias pointing to your source directory. For example:"compilerOptions": {
    "paths": {
    "@/*": ["./src/*"]
    }
    }

Expert Note: This feature significantly improves code readability and maintainability by simplifying import statements.

2. Detect Unused Code

These settings help you identify and remove code that is no longer being used, which can reduce clutter and potential bugs.

  1. No Unused Locals: Set "noUnusedLocals": true. This flags any declared but unused local variables.
  2. No Unused Parameters: Set "noUnusedParameters": true. This flags function parameters that are not used within the function body.

Tip: Unused variables or parameters often indicate typos or leftover code that should be removed.

3. Prevent Typos and Misconfigurations

These options are designed to catch common mistakes and typos that might otherwise go unnoticed.

  1. No Unused Labels: Set "allowUnusedLabels": false. This prevents the use of unused labels, which are an obscure JavaScript feature rarely needed and often a sign of a typo, like accidentally placing a key-value pair outside an object.
  2. No Unchecked Side Effect Imports: Set "noUncheckedSideEffectImports": true. This ensures that if you import a file for its side effects (code that runs upon import), TypeScript will warn you if the file doesn’t actually exist or if there’s a typo in the import path. This prevents silent failures.
  3. No Fallthrough Cases in Switch: Set "noFallthroughCasesInSwitch": true. In switch statements, this requires each case to have a break, return, or similar statement. This prevents unintended code execution in subsequent cases, a common source of bugs.
  4. No Unreachable Code: Set "allowUnreachableCode": false. This flags any code that can never be executed, such as code following a return statement within the same block. Such code is usually dead and can be safely removed.

Warning: If you intentionally want multiple cases in a switch statement to share the same logic, you can list them together like case 'success': case 'error':.

4. Enhance Type Safety with Optional Checks

These settings add an extra layer of safety, particularly when dealing with array elements or object properties.

  1. No Unchecked Index Access: Set "noUncheckedIndexAccess": true. When accessing array elements by index (e.g., myArray[10]), TypeScript will assume the element might be undefined. This forces you to handle cases where the index might be out of bounds, preventing runtime errors. You’ll often need to use optional chaining (?.) to safely access properties.
  2. No Property Access from Index Signature: Set "noPropertyAccessFromIndexSignature": true. This setting helps prevent typos when accessing object properties using dot notation. If an object has an index signature (allowing any string key), this option ensures that dot notation access (e.g., settings.darkMode) only works for explicitly defined properties. For dynamic or custom properties, you must use bracket notation (e.g., settings['customKey']).

Tip: While noUncheckedIndexAccess might require slightly more code for checks, it significantly reduces the risk of runtime errors.

5. Control TypeScript Syntax Transformation

This setting influences how TypeScript features are compiled into JavaScript.

  1. Erasable Syntax Only: Set "},$erasableSyntaxOnly": true. This option restricts you to using TypeScript syntax that can be completely erased during compilation without affecting the runtime JavaScript code. This is useful for environments like Node.js, which primarily strip types without full compilation. It also discourages the use of complex TypeScript features like enums that have runtime equivalents.

Example: Features like class constructor parameter properties (private myProp: string) are transformational. Enabling this setting would flag such usage.

6. Personal Preference Settings

These configurations are based on coding style and specific project needs.

  1. No Implicit Override: Set "noImplicitOverride": true. This is highly recommended when working with classes and inheritance. It requires you to explicitly use the override keyword when overwriting a method from a parent class. This prevents accidental overrides due to typos.
  2. No Error Truncation: Set "noErrorTruncation": true. By default, TypeScript truncates long type error messages to keep them readable. Setting this to true shows the full, un-truncated type information, which can be helpful for debugging complex errors but may result in very long messages.
  3. Exact Optional Property Types: Set "exactOptionalPropertyTypes": true. When a property is optional in a type definition (e.g., name?: string), this setting ensures that the property can either exist with the correct type (string) or not exist at all. It prevents the optional property from being explicitly set to undefined, which can resolve subtle bugs related to property checking (e.g., 'name' in user).

Tip: noErrorTruncation is best used temporarily during debugging complex type issues.

7. Integrating with JavaScript Projects

These settings are invaluable when migrating a JavaScript project to TypeScript or when working with mixed codebases.

  1. Allow JS: Set "allowJs": true. This allows your TypeScript project to import and use JavaScript files. This is essential for gradual migration.
  2. Check JS: Set "checkJs": true. When enabled alongside allowJs, TypeScript will perform type checking on your JavaScript files as well. This helps catch errors in your existing JavaScript code.

Recommendation: If you have a large JavaScript codebase, consider enabling allowJs but initially keeping checkJs as false. Instead, use the //@ts-check comment at the top of individual JavaScript files you want TypeScript to type-check, allowing for a phased approach to type checking.

Conclusion

By implementing these advanced configurations in your tsconfig.json, you can significantly improve the quality and reliability of your TypeScript code. These settings go beyond basic type checking to help you write cleaner, more maintainable, and less error-prone applications.


Source: Strict TypeScript Isn't Enough Anymore (YouTube)

Leave a Reply

Your email address will not be published. Required fields are marked *

Written by

John Digweed

2,092 articles

Life-long learner.