我具有以下通用函数类型:
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 validate<TInput, TOutput>(
value: TInput,
validator: Validator<TInput, TOutput>
): TOutput {}
当然,实际上不需要此功能。实际情况更为复杂,但我已将其简化到最低限度。
这就是为什么Validator
必须通用的原因。
TypeScript缺乏将isNotNull
函数描述为的必要表达能力Validator
。如果TypeScript具有microsoft / TypeScript#17574中所述的任意“通用值” ,则人们可能会说出类似以下内容:
declare const isNotNull: forall T, Validator<T | null, T>; // not valid TS, error
但是目前尚无办法。(有关更多信息,在此问题的答案中,我将继续介绍TypeScript中的泛型。)
如果没有以编程方式执行此操作的能力,则可能需要手动进行操作:
declare const isNotNull: <T>(value: T | null) => Validated<T>;
幸运的是,虽然,而编译器不能表达的是isNotNull
有关Validator
,它可以识别它。所以,你还可以通过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<T | null, T>
T
const getIsNotNull = <T>(): Validator<T | null, T> => isNotNull;
validate(Math.random() < 0.5 ? "hey" : null, getIsNotNull<"hey">());
这使您能够说“isNotNull
与Validator
”有关,但代价是无用的无参数咖喱函数。我更喜欢直接使用validate
with isNotNull
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句