我试图创建一个实用程序类,当某些东西可能未定义时抛出异常,如throwIfUndefined(array[index]).function()
和throwIfUndefined(obj.key).function()
。这是为了使我的代码更简洁,因为使用例如。如果条件和手动抛出是非常冗长的。
我尝试了这个尝试:
export const throwIfUndefined = <T>(v: T | undefined): T => {
if (v === undefined) {
throw new Error("Unexpected undefined");
} else {
return v;
}
};
这主要是工作:
const x = Math.random() < 0.5 ? undefined : 1;
throwIfUndefined(x); // works: type-checks as expected
throwIfUndefined(1); // broken: should give type error because the input can never be undefined
如何修复最后一种情况,以便TypeScript在不必要地使用throwIfUndefined
时捕获?
我试过使用条件类型,但我无法理解它们在这里是如何工作的。
编辑:我不喜欢写的代码的例子
const item = array[index];
if (!item) return;
return item.function() ? 1 : 2;
你必须获取的数组项越多,情况就越糟糕。我宁愿有这样的简写(避免额外的条件和额外的变量):
return throwIfUndefined(array[index]).function() ? 1 : 2
1条答案
按热度按时间nukf8bse1#
我不知道这是不是一个好主意,但可以采取的一种方法是约束泛型类型,以便
undefined
需要可分配给它。这将是一个 * 下限 * 约束,就像说T super undefined
而不是T extends ⋯
,但TypeScript本身不支持下限约束(在microsoft/TypeScript#14520处有一个功能请求)。您可以通过编写以下形式的递归约束来模拟它:这里
T
是v
的类型,函数的返回类型是T & ({} | null)
。类型{} | null
本质上是“除了undefined
之外的所有内容”,所以T & ({} | null)
本质上是“除了删除undefined
之外的T
”。让我们测试一下:对于好的调用,输入类型为
1 | undefined
,输出类型为1
。对于错误的调用,编译器会抱怨number
不能赋值给never
。这可能是一个令人困惑的错误,但是没有microsoft/TypeScript#23689中请求的 invalid types 或 throw types 也没有更好的方法。如果你使用这种方法,你可能会想要很好地记录这个函数,让人们知道发生了什么。Playground链接到代码