Skip to content
/ types Public

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

License

Notifications You must be signed in to change notification settings

poppinss/types

@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 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 to be used 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 is 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()
}

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.

About

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

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published