【问题标题】:"Property ... does not exist on type ..." error when using Typescript使用 Typescript 时出现“属性 ... 类型不存在 ...”错误
【发布时间】:2026-01-19 23:05:02
【问题描述】:

使用 typescript 编译文件时出现错误:

Property 'qaz' does not exist on type '{ bar: string; }'.

文件中有如下代码:

let foo = {
    bar: "Can you perform a Quirkafleeg?"
}

let { qaz = "I'm feeling manic!" } = foo;
console.log(qaz);
console.log(qaz.bar);

基于页面上的示例代码:“解构对象”部分中的https://zellwk.com/blog/es6/

我希望得到第二个字符串作为输出,但我有点困惑,因为该页面上还有另一个示例:

let { fizz: faz = "Eugene was my friend." } = foo; // as defined above
console.log(fizz);
console.log(fizz.faz);

这给出了类似的错误:

Property 'fizz' does not exist on type '{ bar: string; }'.

【问题讨论】:

标签: javascript typescript tsc


【解决方案1】:

这篇文章是关于 ES 解构的,它也是在 typescript 中实现的。然而,Typescript 将执行额外的检查。其中一项检查是您不能从未声明该属性的类型中解构。

所以,这将是一个错误:

let foo = {
    bar: "Can you perform a Quirkafleeg?"
}

let { qaz = "I'm feeling manic!" } = foo; //err

虽然这会起作用:

let foo = {
    bar: "Can you perform a Quirkafleeg?",
    qaz: undefined
}

let { qaz = "I'm feeling manic!" } = foo; //ok qaz is "I'm feeling manic!" because of the default

或者你可以明确指定类型:

let foo: { bar: string, qaz?: string} = {
    bar: "Can you perform a Quirkafleeg?",
}

let { qaz = "I'm feeling manic!" } = foo; //ok qaz is "I'm feeling manic!" because of the default

另一部分是你可以将一个属性解构为一个不同名称的变量,所以下面,我们从foo中取出bar并放入fizz

let foo = {
    bar: "Can you perform a Quirkafleeg?",
    qaz: undefined
}
let { fizz: bar = "Eugene was my friend." } = foo; // basically same as let fizz = foo.bar || "Eugene was my friend."
console.log(fizz); // "Can you perform a Quirkafleeg?" 

但同样的 typescript 限制也适用,在这种情况下 bar 必须在 foo 上定义。

这通常是 typescript 的额外类型检查层,您无法访问 typescript 不知道的属性,无论是通过解构还是通过.[] 直接访问

最后一部分,访问console.log(fizz.faz);永远不会有效,fizz不是原始对象,它是foo.bar中的字符串,所以它不会有属性fazbar .我相信这是您对源博客的误解,我在博客中没有发现任何此类声明。

【讨论】:

  • 如果我错了,请纠正我,但 let { qaz = "I'm feeling manic!" } = foo; //err 不应该通过 tscomplier 抛出错误。他的错误消息是因为试图访问 string 上不存在的属性
  • @Andrei 他提到错误是Property 'qaz' does not exist on type '{ bar: string; }'.,这是 100% 的 TS 编译器错误。
  • 哪个应该被扔到console.log(qaz.bar); 还是足够聪明,可以更早地抓住它?如果他不使用console.log(qaz.bar);,还会出现错误吗?
  • @Andrei 错误发生在解构而不是在 console.log 上,使用 TS 的优点,当你做坏事时一致的错误:) :typescript-play.js.org/#code/…
  • 这真是太棒了,我只有几次机会将 Typescript 用于小型个人项目,我没有意识到它会做那种类型的静态分析。
【解决方案2】:

这不是解构对象的工作方式。

基本上它会查看foo 的子属性并为它们分配新变量

必须与foo的属性名称匹配

例如

const Zell = {
  firstName: 'Zell',
  lastName: 'Liew'
}

let { firstName, lastName } = Zell

console.log(firstName) // Zell
console.log(lastName) // Liew

要修复您的示例,您需要这样做

let foo = {
    bar: "Can you perform a Quirkafleeg?"
}

let { bar } = foo;
console.log(bar);

当您尝试访问 bar 上的“qaz”时,它无法访问,因为 barString

编辑:

在你的例子中展开

let { qaz = "I'm feeling manic!" } = foo; 当您通过=qaz 分配一个值时,如果在对象foo 上找不到它,它实际上只是一个默认值。

在你的例子中

let { fizz: faz = "Eugene was my friend." } = foo; 你试图将fizz 分配给foo.faz 的值,如果fizzfoo 上不存在,它将默认为“Eugene 是我的朋友”。

【讨论】:

  • 它工作正常。 Typescript 编译器存在未知默认参数的问题。
  • @MuratKaragöz 只是向它投掷 any 看起来不像他正在寻找的行为。底层示例是关于访问永远无效的qaz.bar。他正在尝试获取bar,为此他要么需要通过let {qaz: bar = "text"} = foo 使用别名,要么只使用let { bar = "text" } = foo
  • 嗯,对,所以它适用于 Javascript,但不适用于 Typescript。这就解释了为什么它出现在那个关于 Javascript 的页面上。
【解决方案3】:

这是按预期工作的。您正在破坏并为qaz 提供默认参数。它应该可以工作,但似乎 tscompiler 有问题。您可以通过提供 any 类型来修复它,例如

  let foo = { bar: "Can you perform a Quirkafleeg?" }
  let { qaz = "I'm feeling manic!" }: any = foo;
  console.log(qaz); // I'm feeling manic!
  console.log(qaz.bar); // undefined

【讨论】:

  • 值得注意的是,虽然any 将删除错误,但您也可以在这里获得类型安全 - 请参阅@Titian 的回答
最近更新 更多