Using the Construct Signature
feature of TypeScript, you can create a newable function.
/*
* Create a newable function
*/
type Vector2D = {
x: number
y: number
}
type Vector2DConstructor = {
new(x: number, y: number): Vector2D
(x:number, y: number): Vector2D
}
const Vector2D = function (this: Vector2D, x: number, y: number): Vector2D {
if (x < 3) throw new Error('x cannot be smaller than 3')
if (!new.target) {
return {x, y}
}
this.x = x
this.y = y
return this
} as Vector2DConstructor // without type casting, it won't work
const a = new Vector2D(3, 3)
console.log(a)
You can try it on the playground.
There are some drawbacks to this:
- You have to use type-cast, which is not safe for error checking.
- You have to make sure the parameters of the
Constructor
type match the parameters of the function. Otherwise, it will create unexpected errors.
AnyError extends Error
is very specific to this case, becauseError
is not typed as Class in the internals and therefor cannot be simply used astypeof Error
on the right side. – Unconsidered