✨ Become an Affiliate (50%)!

Make your TypeScript smarter - with ONE line of code

·17 min read

Learn how to make your TypeScript inferred types more accurate with ts-reset, a simple, yet powerful library that fixes built-in typings and provides enhanced type safety across your entire project.

TypeScript has revolutionized JavaScript development by providing robust type checking and improved developer experience. However, even with TypeScript's strict mode enabled, there are still gaps in the type system that can lead to runtime errors. This is where the ts-reset library comes into play – a powerful tool designed to fix TypeScript's built-in typings and provide enhanced type safety across your entire project. In this comprehensive guide, we'll explore everything you need to know about the TypeScript reset library, from basic concepts to advanced implementation strategies.

What is ts-reset and why do you need it?

The ts-reset library is essentially the TypeScript equivalent of a CSS reset. Just as CSS resets standardize styling across different browsers by overriding default styles, ts-reset standardizes TypeScript's behavior by fixing inconsistencies and improving the type safety of built-in JavaScript APIs.

Created by Matt Pocock, a TypeScript expert and educator behind Total TypeScript, ts-reset addresses several pain points in TypeScript's standard library typings. It enhances type safety by making TypeScript's type system more accurate and predictable, particularly when dealing with JavaScript's native functions and methods.

ts-reset examples

Key benefits of using ts-reset library

Improved type safety

Eliminates common type-related bugs that TypeScript's default typings miss

Better developer experience

Provides more accurate IntelliSense and autocompletion

Reduced runtime errors

Catches potential issues at compile time that would otherwise only surface during runtime

Standardized behavior

Creates consistency across your codebase for how TypeScript handles built-in JavaScript APIs

Zero runtime overhead

All improvements are at the type level only, with no impact on runtime performance

As one developer put it: "ts-reset is like having a senior TypeScript developer review your code and fix all the subtle type issues before they become bugs."

How to use ts-reset library in your projects

Getting started with ts-reset is straightforward. Let's walk through the installation process and basic setup.

Installation

To add ts-reset to your project, run one of the following commands:

bash npm install @total-typescript/ts-reset

Basic setup

There are two main ways to integrate ts-reset into your project:

Method 1: Import in your entry file

The simplest approach is to import ts-reset at the entry point of your application:

// In your main entry file (e.g., index.ts, main.ts, app.ts)
import "@total-typescript/ts-reset";
 
// Your application code follows...

For more control and better organization, create a dedicated declaration file:

// In a file named 'ts-reset.d.ts' at the root of your project
import "@total-typescript/ts-reset";

Then make sure this file is included in your TypeScript compilation by adding it to your tsconfig.json include array:

{
  "include": ["src/**/*", "ts-reset.d.ts"]
}

Setting up ts-reset in Next.js projects

For Next.js applications, the setup is slightly different:

// In a file named 'reset.d.ts' in your project root
import "@total-typescript/ts-reset";

Then update your tsconfig.json:

{
  "include": ["next-env.d.ts", "reset.d.ts", "**/*.ts", "**/*.tsx"]
}

Diagram showing how ts-reset improves TypeScript's type system by fixing built-in typings

If you're starting a new project and want to ensure type safety from the beginning, consider using a solution like TurboStarter which comes pre-configured with solid TypeScript defaults and can easily integrate tools like ts-reset into your Next.js, React, or mobile application projects.

Best practices for TypeScript reset implementation

To get the most out of ts-reset, follow these best practices:

  1. Apply early in your project lifecycle: Implementing ts-reset from the beginning helps maintain consistency throughout your codebase.

  2. Use in application code, not libraries: As the official documentation warns, ts-reset modifies global typings, so it's not suitable for library code that others will import.

  3. Combine with TypeScript's strict mode: While ts-reset fixes many typing issues, it works best when combined with TypeScript's strict mode for maximum type safety.

  4. Educate your team: Make sure all team members understand what ts-reset does and how it affects the codebase to prevent confusion.

  5. Keep ts-reset updated: Regular updates ensure you benefit from the latest type safety improvements and compatibility with newer TypeScript versions.

What problems does ts-reset solve?

The ts-reset library addresses several critical issues in TypeScript's default type definitions. Let's explore the most significant problems it solves:

How to use ts-reset library with different frameworks

The ts-reset library works well with various frameworks and libraries. Let's look at how to implement it in some popular environments:

Implementing ts-reset in React projects

React projects, especially those bootstrapped with Create React App or using Vite, can easily integrate ts-reset:

// In src/types/reset.d.ts
import "@total-typescript/ts-reset";

For Create React App, update your tsconfig.json:

{
  "include": ["src"]
}

The declaration file will be automatically included since it's in the src directory.

Using ts-reset with Vue.js

For Vue.js projects with TypeScript:

// In src/types/ts-reset.d.ts
import "@total-typescript/ts-reset";

Make sure this file is included in your tsconfig.json:

{
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/types/*.d.ts"]
}

Implementing ts-reset in Angular applications

For Angular projects:

// In src/types/ts-reset.d.ts
import "@total-typescript/ts-reset";

Update your tsconfig.json:

{
  "include": ["src/**/*.ts", "src/types/*.d.ts"]
}

ts-reset vs TypeScript strict mode: What's the difference?

A common question is how ts-reset differs from TypeScript's built-in strict mode. While they both enhance type safety, they serve different purposes:

TypeScript's strict mode is a compiler flag that enables a set of type-checking options:

  • noImplicitAny: Raises errors on expressions with implied any types
  • strictNullChecks: Makes handling of null and undefined more explicit
  • strictFunctionTypes: Enables more accurate function parameter type checking
  • strictBindCallApply: Ensures correct types for bind, call, and apply methods
  • And several other flags Strict mode focuses on how TypeScript performs type checking but doesn't change the underlying type definitions.

Using both together

For maximum type safety, it's recommended to use both strict mode and ts-reset:

// tsconfig.json
{
  "compilerOptions": {
    "strict": true
    // Other compiler options...
  },
  "include": ["src/**/*", "ts-reset.d.ts"]
}

This combination provides both strict type checking and accurate type definitions.

Advanced ts-reset features and customization

Beyond the basic setup, ts-reset offers advanced features and customization options to tailor its behavior to your specific needs.

Selective rule importing

If you don't want all the fixes ts-reset provides, you can selectively import only the rules you need:

// Only import specific rules
import "@total-typescript/ts-reset/filter-boolean";
import "@total-typescript/ts-reset/json-parse";

This approach is useful when you want to gradually adopt ts-reset or when certain fixes conflict with your existing code.

Creating custom type extensions

You can also extend ts-reset with your own custom type fixes:

// In custom-reset.d.ts
import "@total-typescript/ts-reset";
 
// Add your own type extensions
declare global {
  interface Array<T> {
    // Add custom array methods with proper typings
    firstOrNull(): T | null;
  }
}

Combining with other type utilities

ts-reset works well with other TypeScript utility libraries like type-fest or utility-types:

// Import both ts-reset and type-fest
import "@total-typescript/ts-reset";
import type { JsonValue, Promisable } from "type-fest";
 
// Now you can use both together
function processData(data: JsonValue): Promisable<string> {
  // Implementation...
}

What is ts-reset in TypeScript: A deep dive

To truly understand ts-reset, let's examine how it works under the hood and the principles behind its design.

The technical foundation of ts-reset

At its core, ts-reset leverages TypeScript's declaration merging feature to override default type definitions. It uses ambient declarations to modify the global scope without adding any runtime code.

Here's a simplified example of how ts-reset overrides the JSON.parse method:

// Inside ts-reset
declare global {
  interface JSON {
    parse(text: string, reviver?: (key: any, value: any) => any): unknown;
  }
}

This declaration merges with the built-in JSON interface, replacing the return type of parse from any to unknown.

The philosophy behind ts-reset

The ts-reset library follows several key design principles:

  1. Safety over convenience: It prioritizes type safety even if it means requiring more explicit type assertions.

  2. Zero runtime impact: All changes are at the type level only, with no performance overhead.

  3. Minimal changes: It only modifies typings that are demonstrably problematic in real-world code.

  4. Compatibility: It maintains compatibility with existing TypeScript code patterns.

How ts-reset handles DOM types

For browser environments, ts-reset also improves DOM-related typings:

// Without ts-reset
document.querySelector(".element").textContent = "New text";
// Potential error: Object is possibly null
 
// With ts-reset's DOM fixes
document.querySelector(".element")!.textContent = "New text";
// Still requires non-null assertion, but types are more accurate

Common challenges and solutions when using ts-reset library

While ts-reset provides significant benefits, you might encounter some challenges when implementing it:

Best practices for TypeScript type safety beyond ts-reset

While ts-reset significantly improves TypeScript's type safety, it's just one part of a comprehensive type safety strategy. Here are additional practices to enhance your TypeScript development:

Use Zod for runtime validation

Zod is a TypeScript-first schema validation library that ensures your runtime data matches your TypeScript types:

import { z } from "zod";
import "@total-typescript/ts-reset";
 
// Define schema
const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().email(),
});
 
type User = z.infer<typeof UserSchema>;
 
// Parse and validate data
const data = JSON.parse(jsonString);
const user = UserSchema.parse(data); // Throws if validation fails
console.log(user.name); // Safely typed

Implement exhaustive type checking

Use discriminated unions with exhaustive checks:

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "rectangle"; width: number; height: number };
 
function getArea(shape: Shape): number {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "rectangle":
      return shape.width * shape.height;
    default:
      // Exhaustiveness check
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}

Use branded types for added safety

Branded types help prevent mixing values of the same primitive type but different semantic meaning:

type UserId = string & { readonly __brand: unique symbol };
type PostId = string & { readonly __brand: unique symbol };
 
function createUserId(id: string): UserId {
  return id as UserId;
}
 
function getUser(id: UserId) {
  // Implementation...
}
 
const userId = createUserId("user-123");
const postId = "post-456" as PostId;
 
getUser(userId); // OK
getUser(postId); // Error: Argument of type 'PostId' is not assignable to parameter of type 'UserId'

How to use ts-reset library with TypeScript utility types

TypeScript's utility types can be combined with ts-reset for even more powerful type safety:

import "@total-typescript/ts-reset";
 
interface User {
  id: number;
  name: string;
  email: string;
  phone?: string;
}
 
// Create a partial user for updates
function updateUser(userId: number, updates: Partial<User>) {
  // Implementation...
}
 
// Require all fields including optional ones
function createCompleteUserProfile(user: Required<User>) {
  // Implementation...
}

Implementing ts-reset in React projects: A practical guide

React projects benefit greatly from improved type safety, especially as components and state management grow more complex. Let's look at a practical implementation:

// src/types/global.d.ts
import "@total-typescript/ts-reset";

This simple addition ensures type safety across your entire React application. For complex React applications, especially in monorepo setups, this becomes incredibly valuable when working with shared components and data fetching.

When building full-stack applications, ts-reset really shines in handling API responses and state management. If you're working with monorepos managed by Turborepo, check out our ultimate guide to modern JavaScript monorepo management to see how to efficiently structure your TypeScript projects.

React-specific benefits

'@total-typescript/ts-reset';

Future of ts-reset and TypeScript type safety

As TypeScript continues to evolve, what does the future hold for ts-reset and type safety in general?

Upcoming features in ts-reset

The ts-reset library is actively maintained, with several planned improvements:

  1. More DOM-related fixes: Enhanced typings for browser APIs and DOM manipulation
  2. Framework-specific modules: Dedicated modules for React, Vue, and other frameworks
  3. Integration with type testing tools: Better compatibility with libraries like @testing-library/typescript

TypeScript's evolution

TypeScript itself is also evolving, with some of ts-reset's fixes potentially being incorporated into future TypeScript versions. As the TypeScript team continues to improve the standard library typings, the need for some ts-reset features may diminish.

However, JavaScript's dynamic nature means there will likely always be edge cases where additional type safety is beneficial, ensuring a continued role for libraries like ts-reset.

Emerging type safety patterns

Several emerging patterns are shaping the future of TypeScript development:

  1. End-to-end type safety: Full-stack TypeScript applications with shared types between frontend and backend
  2. Type-driven development: Using TypeScript's type system as a design tool
  3. Runtime type validation: Closer integration between compile-time types and runtime validation
  4. AI-assisted type generation: Using AI to generate and improve TypeScript types

Conclusion: Is ts-reset right for your project?

The ts-reset library offers significant benefits for TypeScript projects by enhancing type safety and catching potential bugs at compile time. It addresses critical gaps in TypeScript's standard library typings and provides a more accurate representation of JavaScript's runtime behavior.

When to use ts-reset

Medium to large applications

Where type safety is critical

Teams transitioning from JavaScript to TypeScript

To better understand TypeScript's behavior

Projects with complex data handling

Especially with API responses and JSON data

Applications with external APIs

Where shapes of data may be unpredictable

When ts-reset might not be necessary

  • Small, simple projects with limited scope
  • Library code that will be consumed by others
  • Projects with extensive manual type assertions
  • Teams already using comprehensive validation libraries

Final recommendations

Start with a pilot Implement ts-reset in a small part of your codebase to evaluate its impact

Combine with other tools Use ts-reset alongside validation libraries and utility types

Educate your team Ensure all developers understand the purpose and benefits of ts-reset

Stay updated Keep your ts-reset installation current to benefit from the latest improvements

By thoughtfully integrating ts-reset into your TypeScript workflow, you can significantly enhance your application's type safety and reduce the risk of runtime errors, leading to more robust and maintainable code.

If you're looking to start a new project with all the TypeScript best practices built in, check out TurboStarter - a complete starter kit for building web apps, mobile apps, and browser extensions with robust TypeScript configurations out of the box. You can also use our TurboStarter CLI to get started in seconds with a properly configured TypeScript environment.

For developers focusing on productivity, combining ts-reset with advanced development tools can yield impressive results. Learn how Cursor AI can help you build your startup 10x faster by automatically implementing TypeScript best practices while you code.

ts-reset conclusion

On this page

world map
Community

Connect with like-minded people

Join our community to get feedback, support, and grow together with 100+ builders on board, let's ship it!

Join us

Ship your startup everywhere. In minutes.

Don't spend time on complex setups. TurboStarter simplifies everything.