【问题标题】:TS2339: Property 'props' does not exist on type '{}'TS2339:类型“{}”上不存在属性“道具”
【发布时间】:2019-05-03 02:32:34
【问题描述】:

我正在尝试访问可以是 {} 的对象的属性。

所以我正在做这样的事情:

// component is the object which can be emtpy {}
if (component.children) return method(component.children)

虽然,即使我确保 .children 存在,打字稿仍抱怨它不存在(也在 if 条件下)。

这在 IMO 中很奇怪,因为如果我们断言某个属性存在(或不存在)它为什么会抱怨?


例子:

type OtherType = { name: string };
type TestType = {} | OtherType;

function method(variable: TestType): string {
  if (!variable.name) return ''

  return variable.name;
}

这将抛出Property 'name' does not exist on type '{}'.,正如在TypeScript Playground 中看到的那样

【问题讨论】:

  • 但错误表明您的component 被声明为简单的空对象{},因此当您最后执行component.props 时,该属性不存在。您也应该在 IDE 中看到此错误,而不是在运行时
  • 那么在打字稿中,这些对类型的严格检查不如在 JS 中有用。如果你说你的参数应该是ReactNode,它不能是undefined,这应该会触发一个错误,所以示例你永远不会遇到返回空字符串的情况
  • 如果{} 是唯一的可能性,那会很好,但可以是很多其他包含.props 的对象。 {} 设置为type ReactFragment = {} | ReactNodeArray; 的一种可能性,即使那样它也可能是ReactNodeArray
  • @quirimmo ReactNode 可以是... | null | undefined
  • 是的,我现在正在查看源代码,该类型定义为:type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

标签: javascript typescript


【解决方案1】:

这个错误是有道理的——访问一个可能不存在的属性是不安全的。替换为:

function method(variable: TestType): string {
  if ('name' in variable) {
      return variable.name
  }

  return '';
}

关于你问题的第一部分,如果不知道method 做了什么,很难回答。

【讨论】:

  • 这修复了它!谢谢。你提到访问可能不存在的属性是不安全的,你能解释一下吗?或指向一个帖子?
  • OtherType 是两种对象类型的联合。在联合类型中,它只允许访问存在于两种形状中的属性——因为我们 100% 确定它们会在运行时存在。如果一个属性只存在于一种场景中,我们需要确保我们确实在处理这种场景——我们需要区分并集来区分这两种情况。在这种情况下,if ('name' in variable) 足以证明 TypeScript。在这个if 语句中,它知道访问variable.name 是安全的。
  • 我不明白的是检查 if (variable.name) 不能作为 if ('name' in variable) 工作,两者都检查属性是否已定义(首先确保它不会转换为 false)。那么第二种方法有什么不同呢?
  • 我理解你的观点,我同意。这正是 TypeScript 的工作方式。
【解决方案2】:

我在使用 StencilJS 编码时遇到了这个问题。当您使用 StencilJS 创建 Web 组件时,您还为它定义了一个“标签”属性。然后,您可以在项目的其他任何地方使用该标签来引用它。例如如果您的 Web 组件是 CustomDropdown,您将拥有

    @Component({
    tag: 'custom-dropdown',
    styleUrl: 'customdropdown.scss',
    shadow: false
})

如果你需要在另一个组件中使用这个组件,你只需使用“标签”:

    <custom-dropdown> etc... </custom-dropdown>

如果你使用

    <CustomDropdown> 

你会在属性上得到上述错误。

【讨论】:

  • 这是一个类似的问题,但它似乎是特定于 StencilJS,我建议你用正确的标签打开一个新问题,你可能会更幸运。
猜你喜欢
  • 2018-05-03
  • 2016-03-14
  • 2017-02-25
  • 2021-11-24
  • 2019-01-11
  • 2021-05-08
  • 2021-10-15
  • 2020-12-13
  • 2021-08-04
相关资源
最近更新 更多