类型辅助函数

InferRouteParams

推断路由模式的参数。参数必须按照 AdonisJS 路由语法定义。

import type { InferRouteParams } from '@adonisjs/core/helpers/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

将复杂的 TypeScript 类型美化为简化的类型,以获得更好的查看体验。例如:

import type { Prettify } from '@adonisjs/core/helpers/types'
import type { ExtractDefined, ExtractUndefined } from '@adonisjs/core/helpers/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

原始类型的联合。它包含 null | undefined | string | number | boolean | symbol | bigint

import type { Primitive } from '@adonisjs/core/helpers/types'

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

OneOrMore

指定一个接受 TT[] 的联合类型。

import type { OneOrMore } from '@adonisjs/core/helpers/types'
import type { Primitive } from '@adonisjs/core/helpers/types'

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

Constructor<T, Arguments>

表示一个类构造函数。T 指代类实例的属性,Arguments 指代构造函数的参数。

import type { Constructor } from '@adonisjs/core/helpers/types'

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

AbstractConstructor<T, Arguments>

表示一个也可能是抽象的类构造函数。T 指代类实例的属性,Arguments 指代构造函数的参数。

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

LazyImport

表示一个惰性导入带有 export default 的模块的函数。

import type { LazyImport, Constructor } from '@adonisjs/core/helpers/types'

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

UnWrapLazyImport

解包 LazyImport 函数的默认导出。

import type { LazyImport, UnWrapLazyImport } from '@adonisjs/core/helpers/types'

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

NormalizeConstructor

归一化类的构造函数参数,以便与 mixin 一起使用。该辅助函数是为了绕开 TypeScript issue#37142 而创建的。

// title: 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) {}
//                    ❌ ^^
// title: Using NormalizeConstructor
import type { NormalizeConstructor } from '@adonisjs/core/helpers/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

定义一个不透明类型(opaque type),以区分相似属性。

import type { Opaque } from '@adonisjs/core/helpers/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

从某个不透明类型中解包出值。

import type { Opaque, UnwrapOpaque } from '@adonisjs/core/helpers/types'

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

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

ExtractFunctions<T, IgnoreList>

从对象中提取所有函数。可选地指定一个要忽略的方法列表。

import type { ExtractFunctions } from '@adonisjs/core/helpers/types'

class User {
  declare id: number
  declare username: string

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

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

你可以使用 IgnoreList 来忽略来自已知父类的方法

import type { ExtractFunctions } from '@adonisjs/core/helpers/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'
type UserMethodsWithParent = ExtractFunctions<User, ExtractFunctions<Base>> // 'create' | 'update'

AreAllOptional

检查一个对象的所有顶层属性是否都是可选的。

import type { AreAllOptional } from '@adonisjs/core/helpers/types'

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

ExtractUndefined

提取那些为 undefined 或是带有 undefined 值的联合类型的属性。

import type { ExtractUndefined } from '@adonisjs/core/helpers/types'

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

ExtractDefined

提取那些不为 undefined 且不是带有 undefined 值的联合类型的属性。

import type { ExtractDefined } from '@adonisjs/core/helpers/types'

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

AsyncOrSync

定义一个值或一个该值的 PromiseLike 的联合类型。

import type { AsyncOrSync } from '@adonisjs/core/helpers/types'

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