typescript,无法处理缺失属性的并集。 [tsserver 2339] 类型上不存在属性“数据”

2023-12-26

我有两个对象,一个有属性数据,另一个没有:

const jsonWithNoData = {}
const jsonWithData = { data: [1, 2, 3] }

采取联合后,我尝试执行类型缩小:

const jsonWithNoData = {}
const jsonWithData = { data: [1, 2, 3] }

type JsonWithNoData = typeof jsonWithNoData
type JsonWithData = typeof jsonWithData

type JsonData = JsonWithNoData | JsonWithData // <--- union here

function foo(arg:JsonData) {
  if (arg && arg.data) {
    //           ^^^^<-------[tsserver 2339] Property 'data' does not exist on type 'JsonData'.
    return arg.data
    //         ^^^^<---------[tsserver 2339] Property 'data' does not exist on type 'JsonData'.
  } else {
    return 'no data'
  }
}

console.log(foo({}))

我收到一条错误消息:[tsserver 2339] 类型“JsonData”上不存在属性“数据” 但为什么? union 不是意味着 jsonWithNoData OR jsonWithData 吗?如果是这样,为什么我的类型保护不合法?

上面的片段可以找到

Update: 为了真正说明打字稿cannot查看属性“data”,这不是因为我的类型保护逻辑中的错误,我将上面的内容重写如下:

const jsonWithNoData = {}
const jsonWithData = { data: [1, 2, 3] }

type JsonWithNoData = typeof jsonWithNoData
type JsonWithData = typeof jsonWithData

type JsonData = JsonWithNoData | JsonWithData // <--- union here

function foo(arg:JsonData) {

  const isObject = arg  && (Object.prototype.toString.call(arg) === '[object Object]') 

  if ( isObject && Object.prototype.hasOwnProperty.call(arg, 'data') ) {
    // now we are sure that the property 'data' does exist !! 
    return arg.data
    //         ^^^^<----But we still get error
    //                  [tsserver 2339] Property 'data' does not exist on type 'JsonData'.

  } else {
    return 'no data'
  }
}

console.log(foo({ data: [1, 2, 3] }));

您可以看到类型错误仍然存​​在。 你可以找到更新片段:


在条件下arg && arg.data,变量arg有类型JsonData并且条件的第一部分不缩小这种类型;所以表达式arg.data正在访问一个属性arg可能没有,所以tsc给出类型错误。

是的,在 Javascript 中访问一个不存在的属性是没问题的,并且只会给出undefined,但编译器不想假设当您访问可能不存在的属性时,您知道自己正在这样做并且对此感到满意undefined。如果你写同样的代码思考arg.data是布尔值、数字或字符串属性,您可能期望条件为 false,因为它有一个 false(但不是未定义)值。在这种情况下,编译器会正确地告诉您这一点,因此在其他情况下(例如本例)它也必须给出相同的错误。

你可以改为写arg && 'data' in arg作为条件;这表明你知道arg.data可能不存在,并且还有缩小类型的好处arg在 - 的里面if阻止以便return arg.data类型检查:

if(arg && 'data' in arg) {
//        ^^^^^^^^^^^^^ no type error

    return arg.data;
    //     ^^^ type narrowed by the `in` operator

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

typescript,无法处理缺失属性的并集。 [tsserver 2339] 类型上不存在属性“数据” 的相关文章

随机推荐