npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

toothscript

v0.1.1

Published

A fully typed types for non-typed utility types in typescript

Downloads

41

Readme

toothscript-shaped

🦷 ToothScript

Welcome to the 🦷 ToothScript Types package! This package provides a curated collection of modular and reusable utility types designed to enhance your TypeScript experience without cluttering the global type namespace. Each utility type is crafted with flexibility and modularity in mind, avoiding conflicts with existing TypeScript behavior while offering precise, documented solutions for real-world use cases.

📜 Table of Contents

🌟 Introduction

This package was inspired by the need for better flexibility and extensibility when working with utility types. While TypeScript offers some built-in types like Omit and Pick, its team has decided not to add new utility types globally, citing potential conflicts and varying user preferences.

Instead, this package embraces user-defined utility types to:

  • Avoid conflicts with TypeScript’s standard library.
  • Provide strict, customizable, and modular definitions.
  • Adapt to project-specific needs with ease.

📦 Installation

You can install the package via npm or pnpm:

npm install toothscript
pnpm install toothscript

🛠️ Utility Types Overview

Key Type Modifications

Assert

Ensures specified keys in a type are non-nullable and non-undefined. Useful for strict type validations.

type Assert<T, K extends keyof T> = Omit<T, K> & {
  [P in K]-?: Exclude<T[P], null | undefined>;
};
  • Example:
interface User {
  name?: string;
  email?: string;
  age: number | null;
}

type StrictUser = Assert<User, 'name' | 'email'>;
// { name: string; email: string; age: number | null; }

StrictOmit

Ensures omitted keys exist in the original type.

type StrictOmit<T, K extends keyof T> = {
  [P in Exclude<keyof T, K>]: T[P];
};
  • Example:
interface User {
  name: string;
  email: string;
  age: number;
}

type UserWithoutAge = StrictOmit<User, 'xage'>;  // Error: 'xage' does not exist in User

NullableKeys

Allows a subset of keys in a type to be nullable.

type NullableKeys<T, K extends keyof T = keyof T> = Omit<T, K> & {
  [P in K]: T[P] | null;
};
  • Example:
type User = {
  name: string;
  email: string;
  image: string;
  age: number;
};

type PartialUser = NullableKeys<User, 'image' | 'age'>;
// { name: string; email: string; image: string | null; age: number | null; }

Type Composition and Transformation

This section includes utility types that help compose and transform types.

DeepPartial

Recursively makes all properties of a type optional.

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
  • Example:
interface Complex {
  user: {
    name: string;
    address: {
      street: string;
      city: string;
    };
  };
}

type PartialComplex = DeepPartial<Complex>;
// { user?: { name?: string; address?: { street?: string; city?: string; }; }; }

Negate & Nominal

Negates a type or creates a nominal type.

Negate

Negates a type. excluding the specified type. either by type or by key.

export type ExcludeKeys<T, K extends keyof T> = Omit<T, K>;
export type ExcludeType<T, U> = T extends U ? never : T;

  • Example:
type User = {
  name: string;
  email: string;
  age: number;
};

type UserWithoutAge = ExcludeKeys<User, 'age'>;
// { name: string; email: string; }

type UserWithoutString = ExcludeType<User, string>;
// { age: number; }

Nominal

Creates a nominal type by adding a unique tag to the type. to avoid type compatibility. useful for creating unique types. as a signature type.

export type Nominal<Type, Tag extends string> = Type & { readonly __tag: Tag };
  • Example:
type UserId = Nominal<number, 'UserId'>;
type PostId = Nominal<number, 'PostId'>;

const userId: UserId = 1;
const postId: PostId = 1;

if (userId === postId) {
  // Error: Type 'PostId' is not assignable to type 'UserId'
}

🤔 Why Not Global Utility Types?

The TypeScript team has adopted a No New Utility Types policy for the standard library. The reasons include:

  • Conflicts in Naming: New types often overlap with existing or user-defined types, causing confusion or compatibility issues.
  • Semantics Disputes: Definitions for types like Nullable<T> can vary significantly between users.
  • Breaking Changes: Changing or removing a globally available type can cause significant disruptions in existing projects.

This package avoids these issues by:

  • Offering modular utility types that live only in your project’s namespace.
  • Allowing you to tailor types for your specific needs without relying on TypeScript’s global library.

Key Principles:

  • No global pollution.
  • User-focused modularity.
  • Flexibility for both strict and loose typing requirements.

🛡️ Contributing

We welcome contributions! Whether you find a bug, have a feature request, or want to add new types, feel free to contribute.

  • Fork the repository.
  • Create a new branch for your feature or bug fix.
  • Submit a pull request with a detailed explanation.

📄 License

This project is licensed under the MIT License. You are free to use, modify, and distribute this package as long as the license terms are respected.

💬 Feedback

If you have any suggestions or feedback, feel free to open an issue or contact us directly.


By using this package, you retain full control over type design while adhering to TypeScript’s recommended practices. 🎉