The API is fully typed for TypeScript users (>= 4.7).
Since this package is an ES module, TypeScript must be configured to output ES modules, not CommonJS.
Error classes' and
instances'
props
, aggregate
errors
and
custom
methods/properties are typed.
const BaseError = ModernError.subclass('BaseError', {
props: { userId: 5 as const },
custom: class extends ModernError {
isUserInput() {
return true as const
}
},
})
const error = new BaseError('Wrong user name', {
props: { userName: 'Alice' as const },
})
const { userId, userName } = error // Inferred type: `5` and `"Alice"`
const result = error.isUserInput() // Inferred type: `true`
Error props
without default values can also be typed.
const BaseError = ModernError.subclass('BaseError', {
props: {} as { userId: number },
})
type UserId = InstanceType<typeof BaseError>['userId'] // Type: `number`
custom
options can be typed.
import type { InstanceOptions } from 'modern-errors'
interface InputErrorOptions {
suffix?: string
}
export const InputError = BaseError.subclass('InputError', {
custom: class extends BaseError {
constructor(
message: string,
options?: InstanceOptions & InputErrorOptions,
) {
message += options?.suffix ?? ''
super(message, options)
}
},
})
// Type error: `suffix` must be a string
const error = new InputError('Wrong user name', { suffix: true })
Plugin methods, properties and options are typed.
import ModernError from 'modern-errors'
// This plugin adds a `BaseError.httpResponse(error)` method
import modernErrorsHttp from 'modern-errors-http'
const BaseError = ModernError.subclass('BaseError', {
plugins: [modernErrorsHttp],
})
const error = new BaseError('Wrong user name', {
http: { title: false }, // Type error: `title` must be a string
})
const httpResponse = BaseError.httpResponse(error) // Inferred type: response object
When catching exceptions, their type can be
narrowed
using instanceof
.
const InputError = BaseError.subclass('InputError', {
props: { isUserError: true as const },
})
try {
// ...
} catch (error) {
// Narrows `error` type to `InputError`
if (error instanceof InputError) {
const { isUserError } = error // Inferred type: `true`
}
}
Types are automatically inferred: no explicit type declaration is needed.
typeof
,
ReturnType
,
etc. can be used to retrieve the type of a variable or method.
typeof ExampleError
returns the error class type, while
InstanceType<typeof ExampleError>
(not ExampleError
) returns the error
instance type.
type AnyErrorClass = ReturnType<typeof BaseError.subclass>
const InputError = BaseError.subclass('InputError')
type InputErrorClass = typeof InputError
type InputErrorInstance = InstanceType<InputErrorClass>
const printErrorClass = (ErrorClass: AnyErrorClass) => {
// ...
}
const printInputErrorClass = (InputErrorClass: InputErrorClass) => {
// ...
}
const logInputError = (inputError: InputErrorInstance) => {
// ...
}
printErrorClass(InputError)
printInputErrorClass(InputError)
logInputError(new InputError('Wrong user name'))
The following types are exported:
ErrorInstance
,
ErrorClass
,
ClassOptions
,
InstanceOptions
,
MethodOptions
,
Plugin
and Info
.
Those types are wide: they do not include any information about specific
props
, aggregate
errors
nor
custom
methods/properties. However, they can
include specific plugins' methods, properties and options by passing those as a
generic parameter, such as ErrorClass<[typeof plugin]>
.
They should only be used to type unknown error instances and classes, when no variable nor type inference is available. For example, they can be useful when creating plugins.
For known limitations and issues related to TypeScript's current capabilities, please see the comments in src/main.d.ts.