繁体   English   中英

如何在 TypeScript 中显式键入通用 function?

[英]How to explicitly type a generic function in TypeScript?

问题

我有以下通用 function 类型:

type Validator<TInput, TOutput extends TInput> = (value: TInput) => Validated<TOutput>;

现在我想实现这种类型,所以我做了以下事情:

const isNotNull: Validator<T | null, T> = <T>(value: T | null): Validated<T> => {
    // Implementation here
};

这不起作用,因为在定义之前使用了T

我知道我可以推断出isNotNull的类型,但我想明确地将其声明为Validator作为约束。 我该怎么做呢?


语境

Validator类型将用作 function 参数,如下所示:

function validate<TInput, TOutput>(
    value: TInput,
    validator: Validator<TInput, TOutput>
): TOutput {}

当然实际上不需要这个 function。 实际情况更复杂,但我已将其精简到最低限度。

这就是为什么Validator必须是通用的。

TypeScript 缺乏将isNotNull function 描述为一种Validator所需的表达能力。 如果 TypeScript 具有任意“通用值”,如microsoft/TypeScript#17574中所述,则可能会这样说:

declare const isNotNull: forall T, Validator<T | null, T>; // not valid TS, error

但目前没有办法做到这一点。 (有关更多信息,我在 TypeScript 中的 TypeScript 的答案中关于generics 的 go 。)

如果无法以编程方式执行此操作,您可能需要手动执行此操作:

declare const isNotNull: <T>(value: T | null) => Validated<T>;

不过幸运的是,虽然编译器无法表示isNotNullValidator相关,但它可以识别它。 所以你仍然可以毫无问题地将isNotNull传递给validate()

validate(Math.random() < 0.5 ? 123 : null, isNotNull);
// function validate<number | null, number>(
//   value: number | null, validator: Validator<number | null, number>
// ): number

编译器看到isNotNull可以被视为Validator<number | null, number> Validator<number | null, number>


我能想到的唯一其他方法是表示返回Validator<T | null, T>的通用 function Validator<T | null, T>当您使用T类型参数调用它时,如下所示:

const getIsNotNull = <T>(): Validator<T | null, T> => isNotNull;
validate(Math.random() < 0.5 ? "hey" : null, getIsNotNull<"hey">());

这使您能够说“ isNotNullValidator有关系”,但代价是无用的无参数 curried function。 我更喜欢直接将validateisNotNull一起使用。


Playground 代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM