首页 > 解决方案 > 如何防止包括泛型在内的 Typescript 中的不可为空类型?

问题描述

我的情况与此非常相似:https ://github.com/microsoft/TypeScript/issues/22375 。

那里给出的解决方案大部分都有效,除非我编写一个简单的包装器,只委托给现有的实现。游乐场链接

我无法弄清楚如何更改给定的解决方案以使用通用参数。是否知道我不应该能够做到这一点?还是我错过了什么?

标签: typescripttypescript-generics

解决方案


编译器不能很好地推断一个值是否可以分配给一个依赖于未指定泛型类型参数的类型,T比如. 当类型条件类型(如. 它大多只是放弃并说你写的任何作业都是无效的。DsimpleWrapper()undefined extends T ? any : undefined

有几个开放的 GitHub 问题与此限制有关,但我不知道如果它们得到修复,它们中的任何一个是否会解决这个特定代码的问题。一种是microsoft/TypeScript#13995和/或microsoft/TypeScript#24085:编译器无法根据控制流缩小联合类型的泛型类型参数。另一个是microsoft/TypeScript#33912:编译器无法判断某些东西是否可以分配给通用条件类型,尤其是当它从函数返回时。

我见过的大多数发生此问题的情况都可以通过方便和明智地使用类型断言来解决;知道有些东西是安全的,但编译器却不是。所以就这么说吧:

function simpleWrapper<T, D>(t: T | undefined, d: D): T | D {
  return asDefinedOr(t as any, d);
}

请注意,编译器不再真正尝试为您检查类型安全性,因此您必须小心。


在这种特殊情况下,你会遇到麻烦,想出一个函数,如果它的第一个参数不可能undefined,然后将它包装在一个明确不再关心这个的东西中,因为simpleWrapper(x, 0)不会是一个错误。在这种情况下,您不妨选择原始实现:

function simpleWrapper<T, D>(t: T | undefined, d: D): T | D {
  return t !== undefined ? t : d
}

也许我不了解用例,但我会说要远离条件类型推断杂耍,除非你绝对需要它。


Playground 代码链接


推荐阅读