TypeScript 3.x:访问未知类型的属性
Posted
技术标签:
【中文标题】TypeScript 3.x:访问未知类型的属性【英文标题】:TypeScript 3.x: Access properties of type unknown 【发布时间】:2020-05-07 09:07:46 【问题描述】:我从 TypeScript 文档中了解到,您无法访问未知类型的属性:
// No property accesses, element accesses, or function calls
function f11(x: unknown)
x.foo; // Error
x[5]; // Error
x(); // Error
new x(); // Error
但我不明白为什么?如果我可以分配包括对象在内的每个值,为什么我不能访问属性?
我正在应对以下情况:我有一个 any
类型的对象,我将它传递给 Object.entries
方法,然后调用 forEach
。
因为它是any
类型,所以forEach 调用参数将是一个数组,其中第一个元素为字符串类型,第二个元素为未知类型。
在我的例子中,第二个元素是一个对象,但如果不转换它的类型,我就无法访问它的属性,这似乎是错误的做法。
这是一个示例,它会引发 TS 错误(只是一个抽象,我知道在这种情况下将其声明为 any 没有意义):
const obj: any =
val1: "someval",
val2:
some: "some",
object: "object",
,
;
Object.entries(obj).forEach(el =>
if (el[1].some)
console.log(el);
);
我猜这也可能是 Object.entries
方法的错误类型,但我仍然想解释一下,为什么我不能访问类型为 unknown 的属性。
总结一下,我的问题是:
-
为什么即使未知类型可以是对象,我也无法访问未知类型的属性?
我想上述问题是有原因的,但
Object.entries
不应该返回一个带有元素 nr 的数组。 0 类型的字符串和元素 nr。任何类型的 1 个?
【问题讨论】:
【参考方案1】:我认为,为了解决您的问题,重要的是要提供一些关于 any
与 unknown
的背景信息。虽然您可以在 official TypeScript documentation 中找到详尽的比较列表,但我想我可以冒昧地将文章缩短为几句话:any
基本上是一种万能的,因此 不是类型安全。类型安全是指您可以访问不存在的 any
的运行时属性。
unknown
不同。在这方面unknown
与any
正好相反。它表示any
的类型安全版本,声明“我不会假装我适合所有东西,因为我不适合”。所以unknown
需要额外转换为所需的类型才能工作(因为它本身不具备任何属性)。
现在,进入实际问题。为什么Object.entries
使用unknown
而不是any
?因为说“在使用前将这个未知值转换为你需要的任何值,我不会假设我对这种类型一无所知”比“我不知道它是哪种类型”更安全是,但我会假设它具有所有可能类型的所有可能属性”。
【讨论】:
哦,所以unknown
类型实际上是要“重新分配”给具有可访问属性的类型?所以提醒开发者,在做诸如访问属性之类的事情时,他必须确保它存在,这样他就不会犯可能导致运行时错误的错误。虽然使用 any
类型,但他可以这样做,这可能是错误的,因此不是类型安全的。【参考方案2】:
我也有同样的问题 但我尝试这种技术来解决它
// 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)];
【讨论】:
【参考方案3】:Object.entries(...)
(取自GitHub)的定义是:
entries<T>(o: [s: string]: T | ArrayLike<T>): [string, T][];
由于您将obj
明确定义为any
,因此对Object.entries
的调用返回
[string, unknown][]
您可以在声明 obj
时简单地删除 : any
,TypeScript 将根据定义推断其类型。
在这种情况下,对Object.entries
的调用将返回:
[string, string | some: string; object string; ][]
回答您的问题:
为什么我不能访问未知类型的属性?
编译器试图通过在编译时检查来避免运行时错误。如果您真的知道自己在做什么,您可以随时将unknown
转换为any
。例如:
const value:any = el[1];
我想上述问题是有原因的,但 Object.entries 不应该返回一个带有元素 nr 的数组。 0 类型的字符串和元素 nr。任何类型的 1 个?
它实际上返回[string, unknown][]
。
【讨论】:
我明白,在我的示例中,将其声明为 any 没有任何意义。这只是一个抽象。即当对象来自获取时,它将是任何类型... 我为我的问题添加了摘要。 (我确实知道我的问题有很多解决方法我只是不知道它为什么存在) 感谢您更新的答案,但他们都只是说“是这样”和“它发生了”,但我实际上问为什么是这样,为什么返回类型未知,即使从我的角度来看,any
会更精确以上是关于TypeScript 3.x:访问未知类型的属性的主要内容,如果未能解决你的问题,请参考以下文章