TypeScript 3.x:访问未知类型的属性

jos*_*ias 8 typescript typescript-typings typescript3.0

我从 TypeScript 文档中读到,您无法访问未知类型的属性:

// No property accesses, element accesses, or function calls

function f11(x: unknown) {
    x.foo;  // Error
    x[5];  // Error
    x();  // Error
    new x();  // Error
}

Run Code Online (Sandbox Code Playgroud)

但我不明白为什么?如果我可以分配包括对象在内的每个值,为什么我不能访问这些属性?

我正在与以下场景作斗争:我有一个类型的对象,any我将它传递给Object.entries方法,然后调用forEach.

因为它是 type any,所以 forEach 调用参数将是一个数组,其中第一个元素是 string 类型,第二个元素是 unknown 类型。

在我的情况下,第二个元素是一个对象,但我无法在不转换其类型的情况下访问其属性,这似乎是错误的。

这是一个抛出 TS 错误的示例(只是一个抽象,我知道在这种情况下将其声明为 any 没有意义):

const obj: any = {
  val1: "someval",
  val2: {
    some: "some",
    object: "object",
  },
};
Object.entries(obj).forEach(el => {
  if (el[1].some) {
    console.log(el);
  }
});
Run Code Online (Sandbox Code Playgroud)

错误预览

Object.entries我猜这也可能只是方法的错误类型,但我仍然想解释一下,为什么我不能访问类型未知的属性。

所以作为总结,我的问题是:

  1. 为什么我不能访问类型未知的属性,即使类型未知可以是一个对象?
  2. 我想上述问题是有原因的,但不应该Object.entries返回一个带有元素 nr 的数组。0 类型的字符串和元素 nr。1 任何类型?

Ale*_*eev 7

我认为为了解决您的问题,重要的是提供一些有关anyvs 的背景信息unknown。虽然您可以在TypeScript 官方文档中找到详尽的比较列表,但我想我可以自由地将文章缩短为几个陈述:any基本上是一种类型适合所有,因此不是类型安全的。类型安全是指您可以访问any不存在的运行时属性。

unknown是不同的。在这方面unknown是相反的any。它any通过声明“我不会假装我适合所有东西,因为我不适合”代表了类型安全版本。因此unknown需要对所需类型进行额外的转换才能工作(因为它本身不具有任何属性)。

现在,到实际问题。为什么Object.entries使用unknown而不是any?因为说“在使用之前将这个未知值转换为您需要的任何值,我不会假设我对这种类型一无所知”比“我不知道它是哪种类型,但我会假设”更安全它具有所有可能类型的所有可能属性”。


Elb*_*baz 7

我有同样的问题,但我尝试这种技术来解决它

// choice is a custom data type 
export interface Choice {
  id: string; 
  isSelected: boolean; 
  score: number;
  status: string; 
}
for (const [key, value] of Object.entries(this.tableForm.value)) {
      if (value) {
        let choiceItem  = value as Choice;
        let choiceIds = [String(choiceItem.id)];
         
      }
    }
Run Code Online (Sandbox Code Playgroud)