DEV Community

Dawid
Dawid

Posted on

Simplifying Complex Type Display in TypeScript and VS Code

Introduction:

Complex typescript types can result in a huge confusing mess when hovering on a variable.

This can make it hard to quickly understand the type information.

In this article, we'll explore techniques that can help simplify the display of complex types in VS Code using TypeScript.

The Problem:

Consider the following example where we have a State<T> type and a createState function:

export type State<TStateValue extends StateValue> = {
    // ...
    get: <
        TSelector extends (state: TStateValue) => unknown = (
            state: TStateValue
        ) => TStateValue,
    >(
        selector?: TSelector
    ) => TSelector extends (state: TStateValue) => infer TReturnType
        ? TReturnType
        : TStateValue;
    // ...
};

function createState<T extends StateValue>(initialValue: T): State<T> {
    // ...
}
Enter fullscreen mode Exit fullscreen mode

When using the createState function to create a store with a specific type, like createState(0), VS Code expands the type and displays a verbose and complex type definition:

const numberStore = createState(0);
/*
numberStore: {
  get: <TSelector extends (state: number) => unknown = (state: number) => number>(selector?: TSelector | undefined) => TSelector extends (state: number) => infer TReturnType ? TReturnType : number;
  set: (newValueOrFn: number | ((prev: number) => number)) => void;
  use: <TSelector extends (state: number) => unknown = (state: number) => number>(selector?: TSelector | undefined, equalityFn?: EqualityChecker<...> | undefined) => TSelector extends (state: number) => infer TReturnType ? TReturnType : number;
  onChange: (callback: (value: number, prevValue: number) => void, options?: OnChangeOptions<...> | undefined) => UnsubscribeFn;
}
*/
Enter fullscreen mode Exit fullscreen mode

The Solution: making the type more Opaque

To simplify the display of complex types in VS Code, we can leverage TypeScript's intersection types and a clever type definition. Here's how it works:

  1. Define a Simplify utility type:
export type Simplify<T> = T extends any[] | Date
    ? T
    : {
            [K in keyof T]: T[K];
        } & {};
Enter fullscreen mode Exit fullscreen mode

This type expands objects to show all the key/value types. Given an empty object, it will resolve to an empty object.

  1. Intersect your complex type with Simplify<{}>:
export type State<TStateValue extends StateValue> = {
    // ...
} & Simplify<{}>;
Enter fullscreen mode Exit fullscreen mode

By intersecting the State<T> type with Simplify<{}>, we trigger a mechanism in VS Code that simplifies the displayed type when hovering over variables or types, without altering the actual type.

  1. Use the modified type in the createState function:
function createState<T extends StateValue>(initialValue: T): State<T> {
    // ...
}

const numberStore = createState(0);
// Hovering over `numberStore` will display `State<number>` instead of the expanded type
Enter fullscreen mode Exit fullscreen mode

When using the createState function with the modified State<T> type, VS Code will display the simplified type name State<number> instead of the verbose type definition when hovering over numberStore.

Note: from my experiments, using type NumberStore = State<number> does not achieve the same result. It seems to only work when the type is a return of a function.

Achieving the Reverse effect: expanding the type

Sometimes you may want to expand the whole type to show all the values on hover, instead of showing the Type<Generic>.

The Simplify generic type can help you achieve this

type Input = SomeBuilderType<SomeSuperComplexParsingFunction>
// when you hover on the input, it's to know what the input type is

type ExpandedInput = Simplify<Input>
// ExpandedInput = { id: number } 
Enter fullscreen mode Exit fullscreen mode

Conclusion:

The workaround presented in this article can help simplify the display of complex types in VS Code when working with TypeScript.

I hope this article helps you navigate and simplify the display of complex types in your TypeScript projects using VS Code. Happy coding!

Top comments (0)