创建新实例的curryfied函数的类型



那么,我在ts中有下一个函数:

export function createErrorInstance(error: unknown): Error {
return new Error(getErrorMessage(error));
}

但是现在我想创建一个柯里化函数,它将接受构造函数new Errornew ServiceError,所以以后将返回一个只期望错误的其他函数。

export const errorBuilder  = (builder: new (arg0: string) => any) =>
(error: unknown) => 
new builder(getErrorMessage(error))

可以用作:

export const createErrorService = errorBuilder(ServiceError)

和以后,简单地像:createErrorService(error),如果我在一个尝试/捕获fetch或createValidationError(error),如果我在一个尝试/捕获形式验证。

现在我想设置正确的类型,因为现在我的createErrorService函数的签名是:

const createErrorService: (error: unknown) => any

,但我希望它是:const createErrorService: (error: unknown) => ServiceError

也许我需要更新errorBuilder的签名,但我不知道如何:(

您需要errorBuilder()builder参数构造的Error的子类型中是泛型的。这样的:

export const errorBuilder = <T extends Error>(builder: new (arg0: string) => T) =>
(error: unknown) =>
new builder(getErrorMessage(error));
// const errorBuilder: <T extends Error>(
//   builder: new (arg0: string) => T
// ) => (error: unknown) => T

泛型类型参数T表示您关心的Error的子类型。注意,通过T extends Error声明,它被限制为Error,因此您可以确保T必须可分配给Error。因此,上面所示的errorBuilder的类型是一个函数,它接受T类型的构造函数,并返回一个返回类型为T的函数。

让我们测试一下:

export const createErrorService = errorBuilder(ServiceError);
// const createErrorService: (error: unknown) => ServiceError
const err = createErrorService({ a: 123 });
// const err: ServiceError

看起来不错。createErrorService的类型是(error: unknown) => ServiceError,因此你用它创建的任何错误都是ServiceError

Playground链接到代码

最新更新