【发布时间】:2020-10-05 13:26:21
【问题描述】:
我想创建一个函数,该函数接受一个通常是对象但可能为空/未定义的参数,如果它是非空的,则有条件地返回类型,否则为空。
function objOrNull<T>(t: T): T extends null ? null: T {
if (t == null) return null;
return t;
}
这个函数签名似乎是正确的,我可以用objOrNull({})、objOrNull({a:42})、objOrNull(null)、objOrNull(undefined) 调用它,并且返回的变量具有预期的类型。
但是函数体无法编译,因为return null 和return t 都不能分配给声明的返回类型。
如果我将返回类型声明为T | null,则该函数将编译,但每当我调用它时,我返回的类型可能为 null,这显然不是我想要的 - 应该可以在运行时确定如果 @987654330 @为null返回值也为null,否则不是?
没有添加as any 或类似的丑陋类型转换,是否有“正确”的方式来实现这样的功能?对于一个值,条件类型extends null ? 的等价物是什么?为什么== null 不告诉编译器我处于T extends null 条件中?
(我最初的用例是一个接受对象或 null 的函数,如果对象为 null,则返回 null,否则返回对象的变体,其中添加了一些属性并删除了一些属性,但将问题归结为我的核心问题。) 我原来的用例
【问题讨论】:
-
你试过
=== null吗?我怀疑==可能会欺骗类型检查器,因为0和undefined和其他虚假事物的条件也是如此。 -
对于为什么编译器无法验证依赖于未指定泛型类型参数的条件类型的可分配性,但您的函数没有按照它所说的那样做,有一个规范的答案。
undefined不会扩展null(假设您使用的是--strictNullChecks)。也许您想要类似function objOrNull<T>(t: T): T extends undefined ? null : T { return (typeof t === "undefined") ? null : t; }的东西?该代码有同样的问题,但至少实际上做了你所说的那样。
标签: typescript typescript-generics