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 🙏

© 2026 – Pkg Stats / Ryan Hefner

zod-simple-infer

v1.0.1

Published

A utility type that simplifies Zod's inferred types by expanding them inline

Readme

zod-simple-infer

A zero-runtime utility type that simplifies Zod's inferred types by expanding them inline — making tooltips, diffs, and type errors actually readable.

The Problem

When you use z.infer<typeof schema>, TypeScript preserves Zod's internal type structure. Hovering over the type in your editor shows something like:

const UserSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string().optional(),
});

type User = z.infer<typeof UserSchema>;
//   ^? { name: string; age: number; email?: string | undefined; }
//   ...but often shows as a deeply nested intersection of mapped types

This gets much worse with larger schemas — what you see in your editor is a wall of Pick<...> & Omit<...> or other internal Zod types, not the simple object you defined.

The Solution

Infer flattens the type into a clean, readable shape:

import type { Infer } from "zod-simple-infer";

type User = Infer<typeof UserSchema>;
//   ^? { name: string; age: number; email?: string | undefined }

Same type. Same assignability. Just readable.

Installation

npm install zod-simple-infer
yarn add zod-simple-infer
pnpm add zod-simple-infer
bun add zod-simple-infer

Peer dependency: zod >= 3

Usage

Replace z.infer with Infer anywhere you want cleaner type output:

import { z } from "zod";
import type { Infer } from "zod-simple-infer";

const ProductSchema = z.object({
  id: z.string(),
  name: z.string(),
  price: z.number(),
  tags: z.array(z.string()),
  metadata: z.object({
    createdAt: z.string(),
    updatedAt: z.string().optional(),
  }),
});

type Product = Infer<typeof ProductSchema>;
// {
//   id: string;
//   name: string;
//   price: number;
//   tags: string[];
//   metadata: {
//     createdAt: string;
//     updatedAt?: string | undefined;
//   };
// }

It works with all Zod types — objects, arrays, unions, enums, literals, tuples, records, optionals, nullables, defaults, and more.

Works with any Zod schema

// Enums
const RoleSchema = z.enum(["admin", "user", "guest"]);
type Role = Infer<typeof RoleSchema>; // "admin" | "user" | "guest"

// Records
const ScoresSchema = z.record(z.string(), z.number());
type Scores = Infer<typeof ScoresSchema>; // Record<string, number>

// Tuples
const PairSchema = z.tuple([z.string(), z.number()]);
type Pair = Infer<typeof PairSchema>; // [string, number]

// Unions
const IdSchema = z.union([z.string(), z.number()]);
type Id = Infer<typeof IdSchema>; // string | number

Full type compatibility

Infer<T> is fully assignable to and from z.infer<T> — it's the same type, just displayed differently:

type A = Infer<typeof MySchema>;
type B = z.infer<typeof MySchema>;

// A is assignable to B, and B is assignable to A

How It Works

The entire implementation is a single mapped type:

import type { z } from "zod";

export type Infer<T extends z.ZodType> = {
  [K in keyof z.infer<T>]: z.infer<T>[K];
} & {};

The { [K in keyof T]: T[K] } & {} pattern is a well-known TypeScript trick that forces the compiler to eagerly evaluate and flatten a type, expanding intersections and mapped types into a single object type. The trailing & {} ensures TypeScript doesn't collapse it back.

This package ships only a type declaration (index.d.ts) — zero runtime code, zero bundle impact.

Development

Prerequisites

  • Node.js >= 18
  • npm (or yarn/pnpm)

Setup

git clone https://github.com/purpeon-digital/zod-simple-infer.git
cd zod-simple-infer
npm install

Running Tests

The test suite uses Vitest with --typecheck mode to validate type-level behavior:

npm test

This runs compile-time type assertions defined in index.test-d.ts — no runtime tests needed since the package is types-only.

Contributing

Contributions are welcome! Here's how to get started:

  1. Fork the repository
  2. Clone your fork and install dependencies:
    git clone https://github.com/<your-username>/zod-simple-infer.git
    cd zod-simple-infer
    npm install
  3. Create a branch for your change:
    git checkout -b my-change
  4. Make your changes — if adding new type support, add corresponding test cases in index.test-d.ts
  5. Run the tests to make sure everything passes:
    npm test
  6. Commit and push your branch, then open a Pull Request

Project Structure

zod-simple-infer/
  index.d.ts          # The entire library — one exported type
  index.test-d.ts     # Type-level test suite (Vitest typecheck)
  tsconfig.json       # TypeScript configuration
  package.json        # Package manifest

Guidelines

  • Keep it simple — this package does one thing well
  • All changes should include type tests
  • Ensure npm test passes before submitting a PR

License

MIT © Purpeon Digital AS