javascript - 我可以在打字稿中使用什么来显示两个接口的值之间的关系
问题描述
interface baseVal {
val: string
}
interface parentA{
checker: baseVal
}
interface parentB{
someone: baseVal
}
let test = <T extends parentA | parentB>(param: T) => {
const keys = Object.keys(param) as (keyof T)[]
keys.forEach(key => {
let data = param[key] as baseVal // error
})
}
我目前在“let data = param [key] as baseVal”处遇到错误这是错误状态:
将 'T[keyof T]' 类型转换为 'baseVal' 类型可能是一个错误,因为这两种类型都没有与另一种充分重叠。如果这是故意的,请先将表达式转换为“未知”。
为什么打字稿不明白接口中的值都是相同的类型?如何创建接口以便打字稿知道这种关系?
解决方案
实际上,当您键入 parentA | 时会发生什么?parentB 是一种根本没有键的类型,因为联合(管道)的行为与您在接口情况下所期望的不同。请参阅https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types:
如果一个值的类型为 A | B,我们只知道它有 A 和 B 都有的成员。在此示例中,Bird 有一个名为 fly 的成员。我们不能确定变量类型是否为 Bird | 鱼有飞法。如果变量在运行时确实是 Fish,则调用 pet.fly() 将失败
您可以通过输入一行来验证这一点let x = param.someone.val;
。你会看到param
没有成员的智能感知抱怨someone
。那是因为param
可能是 parentA 类型,在这种情况下,该行将在运行时抛出异常,因为param.someone
未定义。所以简而言之,你不能在这里使用联合类型。
typescript 的主要目的之一是防止由于输入错误导致的运行时错误,因此如果传递给函数的对象可能是两种类型之一,则您不能访问仅属于其中一种类型的字段。在某些情况下,您可以在这种情况下使用链接页面上描述的类型检查,但在您的情况下,问题并不那么容易解决。请注意,您遍历param
. 想象一下,如果这些类型有多个键。typescript 将如何解析 param[key] 的类型?在提供的代码中,人们可以看到类型是什么,但一般来说,这种方法是无效的。因此,如果您想大致保留代码,您可能需要使用以下内容:
interface baseVal {
val: string
}
interface parentA{
checker: baseVal;
}
interface parentB{
someone: baseVal;
}
interface parent {
[key: string]: baseVal;
}
let test = <T extends parent>(param: T) => {
const keys = Object.keys(param) as (keyof T)[]
keys.forEach(key => {
let data = param[key] as baseVal;
})
}
(请注意,如果您的实际类型有更多不同类型的键,这将不合适,但是您的代码无论如何都是无效的。)
推荐阅读
- node.js - PassportJs Google Auth 将现有用户保存为数据库中的新用户。我该如何解决?
- python-3.x - Python 3 尝试/排除最佳实践?
- python - 使用有效负载签署 AWS API 请求
- r - 在具有一百万行的大型数据集上执行 knn 和 lof 以检测 R 中的异常值
- caching - 超线程数据缓存上下文别名
- excel - range.formula = ... Excel 插入一个“@”并打破我希望公式的作用
- python - Python OSError 22 解析存在且具有有效文件名的 XML 文件
- python - 嵌套循环的时间复杂度
- node.js - Gremlin groupCount, order and limit
- css - 我无法将我的 CSS 文件加载到我的 Razor 页面(ASP.Net Core)中