下面是一个简单的打字代码示例.

// Example Setup
declare var foo:{bar?: {baz: string}};
function immediate(callback: () => void) {
  callback();
}

// Type Guard
if (foo.bar) {
  console.log(foo.bar.baz); // ✅ It works!
  immediate(() => {
    console.log(foo.bar.baz); // ❌ TS error : 'foo.bar' is possibly 'undefined'.(18048)
  });
}

foo.bar具有类型保护以确保它不是空值,实际上,foo.bar被推断为类型{baz: string}.

但是,我不知道为什么立即回调函数中会出现打字错误,说foo.bar可能是未定义的.导致此错误的原因是什么?

推荐答案

发生这种情况的原因是类型脚本不知道回调函数何时被调用,因此它不知道类型收缩是否仍然有效.任何任意代码都可以在这之间运行并对foo进行更改.

最简单的解决方案是将你正在判断的东西分配给const分.这样,TypeScrip就知道它不能更改,因此缩小文字范围必须仍然有效.

const temp = foo.bar;
if (temp) {
  console.log(temp.baz);
  immediate(() => {
    console.log(temp.baz);
  });
}

PS版本5.4( compose 本文时还处于测试阶段)改进了对一些类似案件的处理.但是Jcalztry 了您的 case ,它仍然会有这个问题.欲了解更多信息,请访问:https://devblogs.microsoft.com/typescript/announcing-typescript-5-4-beta/#preserved-narrowing-in-closures-following-last-assignments

Typescript相关问答推荐

忽略和K的定义

使某些类型的字段变为可选字段'

在NextJS中获得Spotify Oauth,但不工作'

基于键的值的打字动态类型;种类;

我想创建一个只需要一个未定义属性的打字脚本类型

类型脚本返回的类型包含无意义的泛型类型名称

等待用户在Angular 函数中输入

迭代通过具有泛型值的映射类型记录

如何在Vue中使用Enum作为传递属性的键类型?

使用动态输出类型和泛型可重用接口提取对象属性

如何在typescript中为this关键字设置上下文

下载量怎么会超过下载量?

vue-tsc失败,错误引用项目可能无法禁用vue项目上的emit

为什么TypeScrip不能解析对象析构中的赋值?

VITEST警告:当前的测试运行器不支持After Each/teardown挂钩

仅当类型为联合类型时映射属性类型

如何使对象同时具有隐式和显式类型

Typescript:是否将联合类型传递给重载函数?

必须从注入上下文调用Angular ResolveFn-inject()

如何强制对象数组中的对象属性具有非空字符串值?