【问题标题】:Check for optional properties in typescript检查打字稿中的可选属性
【发布时间】:2019-09-17 22:22:25
【问题描述】:

考虑以下接口

interface Foo {
  bar?: Bar;
}

interface Bar {
  baz?: Baz;
}

interface Baz {
  foobar: number;
}

我认为这是访问数据的一种安全方式:

const test = (foo: Foo) => {
  const baz = (foo.bar || {}).baz || {};
  const foobar = baz.foobar;
};

但是,它会导致错误:(298, 26) TS2339: Property 'foobar' does not exist on type '{}'。

好的。但是我不会假设这会产生不同的结果:

const test = (foo: Foo) => {
  const baz = (foo.bar || {}).baz;
  const foobar = ({} || baz).foobar;
};

虽然这是一种解决方法,但我对它不是很满意,因为我经常使用 baz 来获取更多属性。对我来说,这似乎是一个打字稿错误。

【问题讨论】:

  • 如果您查看const baz = (foo.bar || {}).baz || {}; 这一行,您将看到两个分支,应该由 TS 检查。因为baz 属性的类型是Baz,但{} 的类型是{},它不包含foobar
  • 第一次尝试将baz 变量设置为Baz | {}。第二个将baz 设置为Baz | undefined。此外,在第二次尝试中,您颠倒了{}baz 的顺序,所以它总是会导致{}
  • 您的第二个代码块也出现错误:link。据我所知,这不是 TypeScript 错误。我在您的文字中没有看到实际问题,所以我不确定您想要什么答案。

标签: typescript


【解决方案1】:

我对您的示例并不完全清楚(它们似乎都以非常相似的方式失败)。不过没关系;现在,您在这里尝试执行的嵌套可选属性查找的最佳方法是这样的:

const test = (foo: Foo) => {
  const foobar = foo.bar && foo.bar.baz && foo.bar.baz.foobar;
};

它会起作用,但它并不漂亮。不过,有一些库可以使这个更好,例如typesafe-get:

const test = (foo: Foo) => {
  const foobar = get(foo, 'bar', 'baz', 'foobar');
};

不过,从中期来看,真正的解决方案是optional chaining。这是一个新的 JavaScript 功能,应该会在今年 11 月登陆 TypeScript 3.7。看起来像这样:

const test = (foo: Foo) => {
  const foobar = foo?.bar?.baz?.foobar;
};

【讨论】:

  • 我等不及可选链接了!多年来 TypeScript 的好消息!
猜你喜欢
  • 2018-06-05
  • 2019-04-18
  • 2015-05-26
  • 1970-01-01
  • 2016-11-01
  • 2021-12-30
  • 2021-11-17
  • 2021-11-30
  • 2019-12-22
相关资源
最近更新 更多