【问题标题】:TypeScript says 'Object is possibly null' even though I explicity set itTypeScript 说“对象可能为空”,即使我明确设置了它
【发布时间】:2020-11-24 13:15:46
【问题描述】:

所以我有一个接口PropertyValue,其中属性descr_json要么是一个对象,要么是null:

export interface Property {
    descr_json: Array<string>;
    descr: string;
    id: number;
}

export interface PropertyValue {
    descr_json: { [key: string]: string } | null;
    descr: string | number | null;
    id?: number;
}

然后在我的代码中,有时我会尝试将值添加到 PropertyValue 对象的 descr_json 属性:

if (property.descr_json && property.descr_json.length) {
    propertyValue.descr_json = {};
    property.descr_json.forEach(subProperty => {
        propertyValue.descr_json[subProperty] = '';
    });
}

但在forEach 内部,TS 抱怨propertyValue.descr_json 可能为空,即使我在前一行明确将其设置为空对象。

我当然可以用一个额外的if 语句包围它,以检查descr_json 实际上是否为空,但这似乎是多余的,因为我已经知道了

我在这里错过了什么?

【问题讨论】:

  • descr_json[subProperty] 因此descr_json 没有提到那个权利吗?所以它是未定义的
  • 你在一个对象上使用.length.forEach()
  • 不,property.descr_json 是一个数组 :) pValues.descr_json 是一个对象。
  • 您显示了两个变量 propertypValues 但只有一个接口 PropertyValue 并且没有类型声明(在分配或任何地方)。我们怎么知道如何调试它?
  • 我的错,我假设对象具有相同的形状,因为它们具有相同的属性descr_json

标签: javascript typescript


【解决方案1】:

我相信您可以使用non null assertion operator 告诉转译器,即使它可能为空,也请将其视为绝对不为空,

在需要将其视为“真正不为空”的情况下,使用非空断言运算符(感叹号)对其进行后缀

我认为转译器并不关心你是否定义了它,它只关心类型是什么以及它的 nullable 在打字稿意义上是不是这个词,(即数字?还是字符串?)然后它的类型实际上是 string | nullnumber | null 并且 transpire 不会关心您是否明确设置它。这是我相信的,如果我错了,请纠正我

  var x : string | null = null
  var y = x.substring(0, x.length / 2); // oop! it could be null compilation error
  var y = x!.substring(0, x!.length / 2); // use of assert non null operator prevents transpilation error

另一种可能的替代方法是使用正确类型的临时对象,然后将其分配给descr_json

const temp: { [key: string]: string } = {};
property.descr_json.forEach(subProperty => {
  temp[subProperty] = '';
});
pValues.descr_json = temp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多