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

@poppinss/types

v1.2.1

Published

A collection of types-only helpers used across all the AdonisJS, Edge, VineJS, and Japa packages

Readme

@poppinss/types

A collection of types-only helpers used across all the AdonisJS, Edge, VineJS, and Japa packages

gh-workflow-image npm-image license-image

Usage

This package contains types-only helpers with no runtime code. You can install it from the npm packages registry.

npm i @poppinss/types

Helpers

Following is the list of available helpers

InferRouteParams<Identifier>

Infer params of a route pattern. Helper supports the AdonisJS routing syntax only.

import type { InferRouteParams } from '@poppinss/types'

InferRouteParams<'/users'> // {}
InferRouteParams<'/users/:id'> // { id: string }
InferRouteParams<'/users/:id?'> // { id?: string }
InferRouteParams<'/users/:id/:slug?'> // { id: string; slug?: string }
InferRouteParams<'/users/:id.json'> // { id: string }
InferRouteParams<'/users/*'> // { '*': string[] }
InferRouteParams<'/posts/:category/*'> // { 'category': string; '*': string[] }

Prettify<T>

Prettifies the complex TypeScript types to a simplified type for a better viewing experience. For example:

import type { Prettify } from '@poppinss/types'
import type { ExtractDefined, ExtractUndefined } from '@poppinss/types'

type Values = {
  username: string | undefined
  email: string
  fullName: string | undefined
  age: number | undefined
}

// When not using prettify helper
type WithUndefinedOptional = {
  [K in ExtractDefined<Values>]: Values[K]
} & {
  [K in ExtractUndefined<Values>]: Values[K]
}

// When using prettify helper
type WithUndefinedOptionalPrettified = Prettify<
  {
    [K in ExtractDefined<Values>]: Values[K]
  } & {
    [K in ExtractUndefined<Values>]: Values[K]
  }
>

Primitive

Union of primitive types. It includes null | undefined | string | number | boolean | symbol | bigint

import type { Primitive } from '@poppinss/types'

function serialize(
  values:
    | Primitive
    | Record<string, Primitive | Primitive[]>
    | Primitive[]
    | Record<string, Primitive | Primitive[]>[]
) {}

OneOrMore<T>

Specify a union that accepts either T or T[].

import type { OneOrMore } from '@poppinss/types'
import type { Primitive } from '@poppinss/types'

function serialize(
  values: OneOrMore<Primitive> | OneOrMore<Record<string, Primitive | Primitive[]>>
) {}

Constructor<T, Arguments>

Represent a class constructor. The T refers to the class instance properties, and Arguments refers to the constructor arguments.

import type { Constructor } from '@poppinss/types'

function make<Args extends any[]>(Klass: Constructor<any, Args>, ...args: Args) {
  return new Klass(...args)
}

AbstractConstructor<T, Arguments>

Represent a class constructor that could also be abstract. The T refers to the class instance properties, and Arguments refers to the constructor arguments.

import type { AbstractConstructor } from '@poppinss/types'
function log<Args extends any[]>(Klass: AbstractConstructor<any, Args>, ...args: Args) {}

LazyImport<DefaultExport>

Represent a function that lazily imports a module with export default.

import type { LazyImport, Constructor } from '@poppinss/types'

function middleware(list: LazyImport<Constructor<{ handle(): any }>>[]) {}

UnWrapLazyImport<Fn>

Unwrap the default export of a LazyImport function.

import type { LazyImport, UnWrapLazyImport } from '@poppinss/types'

type Middleware = LazyImport<Constructor<{ handle(): any }>>
type MiddlewareClass = UnWrapLazyImport<Middleware>

NormalizeConstructor<T>

Normalizes the constructor arguments of a class for use with mixins. The helper is created to work around TypeScript issue#37142.

Usage without NormalizeConstructor

class Base {}

function DatesMixin<TBase extends typeof Base>(superclass: TBase) {
  // A mixin class must have a constructor with a single rest parameter of type 'any[]'. ts(2545)
  return class HasDates extends superclass {
    //          ❌ ^^
    declare createdAt: Date
    declare updatedAt: Date
  }
}

// Base constructors must all have the same return type.ts(2510)
class User extends DatesMixin(Base) {}
//                    ❌ ^^

Using NormalizeConstructor

import type { NormalizeConstructor } from '@poppinss/types'

class Base {}

function DatesMixin<TBase extends NormalizeConstructor<typeof Base>>(superclass: TBase) {
  return class HasDates extends superclass {
    declare createdAt: Date
    declare updatedAt: Date
  }
}

class User extends DatesMixin(Base) {}

Opaque<T>

Define an opaque type to distinguish between similar properties.

import type { Opaque } from '@poppinss/types'

type Username = Opaque<string, 'username'>
type Password = Opaque<string, 'password'>

function checkUser(_: Username) {}

// ❌ Argument of type 'string' is not assignable to parameter of type 'Opaque<string, "username">'.
checkUser('hello')

// ❌ Argument of type 'Opaque<string, "password">' is not assignable to parameter of type 'Opaque<string, "username">'.
checkUser('hello' as Password)

checkUser('hello' as Username)

UnwrapOpaque<T>

Unwrap the value from an opaque type.

import type { Opaque, UnwrapOpaque } from '@poppinss/types'

type Username = Opaque<string, 'username'>
type Password = Opaque<string, 'password'>

type UsernameValue = UnwrapOpaque<Username> // string
type PasswordValue = UnwrapOpaque<Password> // string

ExtractFunctions<T, IgnoreList>

Extract all the functions from an object. Optionally specify a list of methods to ignore.

import type { ExtractFunctions } from '@poppinss/types'

class User {
  declare id: number
  declare username: string

  create() {}
  update(_id: number, __attributes: any) {}
}

type UserMethods = ExtractFunctions<User> // 'create' | 'update'

You may use the IgnoreList to ignore methods from a known parent class

import type { ExtractFunctions } from '@poppinss/types'

class Base {
  save() {}
}

class User extends Base {
  declare id: number
  declare username: string

  create() {}
  update(_id: number, __attributes: any) {}
}

type UserMethods = ExtractFunctions<User> // 'create' | 'update' | 'save'
type UserMethodsWithParent = ExtractFunctions<User, ExtractFunctions<Base>> // 'create' | 'update'

AreAllOptional<T>

Check if all the top-level properties of an object are optional.

import type { AreAllOptional } from '@poppinss/types'

AreAllOptional<{ id: string; name?: string }> // false
AreAllOptional<{ id?: string; name?: string }> // true

ExtractUndefined<T>

Extract properties that are undefined or are a union with undefined values.

import type { ExtractUndefined } from '@poppinss/types'

type UndefinedProperties = ExtractUndefined<{ id: string; name: string | undefined }>

ExtractDefined<T>

Extract properties that are not undefined nor is a union with undefined values.

import type { ExtractDefined } from '@poppinss/types'

type UndefinedProperties = ExtractDefined<{ id: string; name: string | undefined }>

AsyncOrSync<T>

Define a union with the value or a PromiseLike of the value.

import type { AsyncOrSync } from '@poppinss/types'

function log(fetcher: () => AsyncOrSync<{ id: number }>) {
  const { id } = await fetcher()
}

DeepPartial<T>

Mark nested properties as partial until unlimited depth.

import type { DeepPartial } from '@poppinss/types'

type Config = {
  http: {
    bodyParser: {
      enabled: boolean
    }
    qs: {
      parse: {
        quotes: boolean
      }
    }
  }
}

export function defineConfig(config: DeepPartial<Config>): Config {}

Contributing

One of the primary goals of Poppinss is to have a vibrant community of users and contributors who believes in the principles of the framework.

We encourage you to read the contribution guide before contributing to the framework.

Code of Conduct

In order to ensure that the Poppinss community is welcoming to all, please review and abide by the Code of Conduct.

License

@poppinss/types is open-sourced software licensed under the MIT license.