Is there a way to create a Type Guard function for possibly undefined object and check a field and infer the parent object is not undefined?

huangapple go评论118阅读模式
英文:

Is there a way to create a Type Guard function for possibly undefined object and check a field and infer the parent object is not undefined?

问题

有一个可能未定义的对象,是否有一种方法可以创建一个类型守卫函数,以便如果我使用可选链接来检查字段是否有效,TypeScript 可以推断对象本身也是已定义的值?

```ts
function isNotUndefined<T>(
	arg: T
): arg is Exclude<T, undefined> {
	return arg !== "undefined";
}

let someVal: { foo: "string"; bar: "string" } | undefined;

if (isNotUndefined(someVal?.foo)) {
	console.log(someVal.foo); // 抛出错误:TS18048:“someVal”可能是“undefined”。
}

if (someVal?.foo !== undefined) {
	console.log(someVal.foo);
}

在第二个示例中,我的IDE(Webstorm)仍然警告我可能未初始化s,但除此之外不会抛出错误。我尝试将isNotUndefined的类型更改为unknown而不是T,但也不起作用。理想情况下,我希望找到一种方法使这个函数与isNotUndefined函数一起工作,因为我们在各个地方都使用它来进行类型守卫,而不仅仅是在对象的情况下,我不想为对象专门创建这个函数的独立版本...


<details>
<summary>英文:</summary>

Say I have an object that may be undefined, is there a way to make a Type Guard function so that if I use optional chaining to check if a field is valid, that TypeScript can infer the object itself is also a defined value?

```ts
function isNotUndefined&lt;T&gt;(
	arg: T
): arg is Exclude&lt;T, undefined&gt; {
	return arg !== &quot;undefined&quot;;
}

let someVal: { foo: &quot;string&quot;; bar: &quot;string&quot; } | undefined;

if (isNotUndefined(someVal?.foo)) {
	console.log(someVal.foo); // Throws Error: TS18048: &#39;someVal&#39; is possibly &#39;undefined&#39;.
}

if (someVal?.foo !== undefined) {
	console.log(someVal.foo);
}

In the second instance my IDE (Webstorm) still warns me that someVal might not have been initialized, but it other than that it doesn't throw an Error. I've tried updating the typing for the isNotUndefined to be unknown instead of T, but that doesn't work either. Ideally, I'd like to come up with a way to make this work with the isNotUndefined function, as we use that for type guarding all over, not just in the case of objects, and I'd hate to have to make a separate version of this function exclusively for objects...

答案1

得分: 1

截止到TypeScript 5.1版本,目前不可能实现这个功能,如microsoft/TypeScript#34974所述。当前,类型守卫函数仅在参数是变量或直接对象属性访问表达式时才起作用。但是,someVal?.foo既不是变量也不是直接对象属性访问表达式,因此它不会进行任何缩小范围的操作。

然而,还是有一些希望可以改变这一情况。该问题标记为Help Wanted,这意味着欢迎提出解决方案的拉取请求(需符合贡献指南的准则)。因此,任何关心这个问题并希望看到它得以实现的人都应该考虑自己采取行动!

英文:

As of TypeScript 5.1, this is not currently possible, as described in microsoft/TypeScript#34974. Right now a type guard function only acts on an argument if it's a variable or direct object property access expression. But someVal?.foo is neither of those, so it doesn't do any narrowing.

There is some hope that this could change, though. The issue is marked as Help Wanted, meaning that pull requests addressing it are welcome (subject to the guidelines for contributing). Anyone who cares enough about this to see it implemented should therefore consider doing so themselves!

huangapple
  • 本文由 发表于 2023年8月11日 01:16:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76877978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定