打字稿:无法确定财产

时间:2021-07-20 08:20:34

标签: typescript

function aaa(cell: unknown): void {
  if(cell && typeof cell == 'object' && cell.hasOwnProperty('display') && 'display' in cell) {

    console.log(cell.display)
  }
}

出现错误 - 类型“对象”上不存在属性“显示”。(2339)

Playground link

有人知道为什么吗?

3 个答案:

答案 0 :(得分:2)

发生这种情况是因为您将 cell 的类型定义为 unknown。如果您将其定义为 any,那么它将起作用。

有关两者之间差异的更多背​​景信息,请参阅 this answer

来自 the announcement 关于 unknown

<块引用>

我们经常想在 TypeScript 中描述能力最低的类型。这对于想要发出信号“这可以是任何值,因此您必须在使用之前执行某种类型的检查”的 API 很有用。这会强制用户安全地内省返回值。

如果您想使用 unknown,那么您应该按照公告 like so 中的建议将类型检查移至不同的功能:

function hasDisplay(obj: any): obj is { display: any } {
    return !!obj && typeof obj === "object" && "display" in obj;
}

function aaa(cell:unknown): void {
  if (hasDisplay(cell))
    console.log(cell.display)
  }
}

然后这应该编译。

答案 1 :(得分:0)

因为实际上 cell 是一个 unknown 对象,因此 Typescript 无法推断出您试图访问的属性。

正如 Simona 在她的回答中所说,如果您改为使用 any,它不会抱怨,因此我 recommend checking this Stack Overflow 质疑 any 和 {{1} 之间的差异}.

不过我会尽可能地追求,键入参数,或者最终一旦您确定未知不再是未知,您就可以将其强制为您期望的类型。

答案 2 :(得分:0)

您可以使用强制转换((<T>obj).x,其中 T 是类型,obj 是您的对象实例来访问属性/方法 x)。

在您的情况下,您将文件定义为 JSX,它尝试将所有 <x> 解析为一个标签,因此您可以使用 as 运算符 (obj as T).x 来转换您的对象。

如果你的对象继承了一个特定的类型,或者它编译成JS然后类型无关紧要,你甚至可以转换成你想要的类型,但如果你不这样做,你就不知道类型,而且你的函数很简单,以后不会麻烦你了,你可以用any代替T


function aaa(cell: unknown): void {
  if(cell && typeof cell == 'object' && cell.hasOwnProperty('display') && 'display' in cell) {

    console.log((cell as any).display)
  }
}

aaa({display: 'abc'})

如您所见,类型不同但可以解析

class MyType {
  public display:string|undefined;
}

function aaa(cell: unknown): void {
  if(cell && typeof cell == 'object' && cell.hasOwnProperty('display') && 'display' in cell) {

    console.log((cell as MyType).display)
  }
}

class XyzType {
  public constructor(display:string){
    this.display = display;
  }

  public display:string|undefined;
}
aaa(new XyzType('abc'))