【问题标题】:How to access non-existing property correctly in Typescript如何在 Typescript 中正确访问不存在的属性
【发布时间】:2021-10-20 04:50:45
【问题描述】:

我正在尝试编写这段代码,如果属性不存在,则从具有默认值的对象数组中提取布尔值

const flagArrayToBooleanArray_INITIAL_ERROR = (
  arr: Array<{ value: string } | { value: string; flag: true }> = [{
    value: "",
  }, { value: "", flag: true }],
) => {
  const flags: Array<boolean> = arr.map((obj) => obj.flag ?? false);
  return flags;
};

}

Typescript 抱怨函数 ({ flag }) =&gt; flag ?? false 因为属性 flag 在类型 Empty | { flag: true } 上不存在

这可以通过将对象转换为地图来解决

function flagArrayToBooleanArrayFixedMap(
  arr: Array<{ value: string } | { value: string; flag: true }> = [{ value: "" }, { value: "", flag: true }],
) {
  return arr.map((obj) => {
    const tmp = new Map(Object.entries(obj));

    return tmp.get("flag") === true ? true : false;
  });
}

有没有办法告诉打字稿I know this might not exist, I want the default js behaviour in this case

playground link

编辑:修复了一些复制粘贴错误,在初始代码中没有编译器错误。

【问题讨论】:

  • @T.J.Crowder 它工作,但如果你从const flags: Array&lt;boolean&gt; 中去掉硬输入,编译器认为flagstrue[]。如此有效,但很时髦(如果有 flag 属性,它必须是真的,所以映射的结果是 true[])。
  • @T.J.Crowder 如果您将鼠标悬停在.map 上。具体或者去掉flags的类型,可以看到是true[]。由于.map 专门迭代{ flag },并且具有flag 属性的项目都是true,因此?? false 永远不会发挥作用,除非你对编译器撒谎.
  • @crashmstr - 看到了吗?我很密集。 :-D 你说,就在你之前的评论中。这似乎不是 OP 所要求的,但它确实需要修复。
  • @T.J.Crowder,谢谢你的建议,以后我会尽量多在场,
  • @afiori - 谢谢。您可以编辑问题以更正或扩展它。 (这样做时,重要的是要小心不要使现有答案无效或合并现有答案。)

标签: javascript typescript typeerror


【解决方案1】:

如果您的项目可能有也可能没有标志,那么在较高的位置正确键入会更容易。

您还可以定义可能具有或不具有标志属性的类型。任何对象都可以“满足”该标准(但可能是undefined)。

type MayHaveFlag = { flag?: boolean };

function flagArrayToBooleanArray(
  arr: MayHaveFlag[]
) {
  const flags = arr.map(({ flag }) => !!flag);
  return flags;
}

const values = [{}, {}, { flag: true }, { dont: 'care', what: 'this', has: 1 }];
const result = flagArrayToBooleanArray(values);
console.log(result);

所以在这里,当我们.map 覆盖对象时,我们会得到truefalseundefined,因为其中任何一个都可能是来自任何对象的值。然后我们可以使用!! 强制转换为truefalseundefined 变为false,其他值保持不变)或者如果您愿意,您可以保留flag ?? false,因为那样会做同样的事情东西。

您可以注意到我的values 数组甚至不需要声明类型,因为函数参数实际上对对象没有任何要求,除非它具有flag 属性,它是boolean

TypeScript Playground

【讨论】:

  • 谢谢,这看起来是正确的惯用方式;在这种情况下,我不想更改函数的签名,所以我选择在映射中检查 `("flag" in obj)` 以使编译器满意。
猜你喜欢
  • 2019-07-27
  • 2013-10-17
  • 1970-01-01
  • 2020-10-07
  • 2017-03-02
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多