Skip to content

shoooe/derive

Repository files navigation

Derive

npm version

Utility type to generate a type from another with a special care for the DX.

You can see this tool as an hardcode version of Pick.

Features:

  • 😎 Type safe
  • 🌱 Minimal & lightweight
  • ⌨️​ Autocompletion for fields
  • 💥 Automatically expands arrays and nullable/optional types
  • 👀 Preview expanded types in intellisense
  • 💫 Supports recursive & mutually recursive types
  • ❓ Optional fields support
  • 💋 Inspired by GraphQL

Installation

yarn add @shoooe/derive

Usage

Basic usage

Let's say that we have a type User defined as:

type User = {
  bestFriend: User | undefined;
  favoriteBook: Book | null;
  friends: User[] | undefined;
  id: number;
  name: string;
};

type Book = {
  author: User;
  isdn: number;
  synopsis: string | null;
  title: string | null | undefined;
  subtitle?: string | null;
};

We can derive a subset of its properties via:

type Result = Derive<
  User,
  {
    id: true;
    name: true;

    // Automatically expands nullable & optional types, which means that `null`
    // and `undefined` will be added automatically to the resulting type if
    // they existed in the target type.
    bestFriend: {
      name: true;
    };

    // Automatically expands arrays as well
    friends: {
      name: true;

      // Supports mutually recursive types
      favoriteBook: {
        isdn: true;
        title: true;
        synopsis: true;
        author: {
          name: true;
        };
      };
    };
  }
>;

Which will result in:

type Result = {
  id: number;
  name: string;
  bestFriend:
    | {
        name: string;
      }
    | undefined;
  friends:
    | {
        name: string;
        favoriteBook: {
          isdn: number;
          title: string | null | undefined;
          synopsis: string | null;
          author: {
            name: string;
          };
        } | null;
      }[]
    | undefined;
};

Alternatives

  • ts-essentials: comprehensive library with a different style for DeepPick (it doesn't do automatic expansion)

Credits

Special thanks to:

  • Perdoo for sponsoring the initial research & implementation
  • Szaman for the initial code review