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”处收到错误 这就是错误的内容:
Conversion of type 'T[keyof T]' to type 'baseVal' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
为什么 typescript 不理解接口(interface)中的值都是相同的类型? 如何创建接口(interface)以便 typescript 知道这种关系?
最佳答案
实际上,当您输入parentA | 类型时会发生什么? ParentB 是一种根本没有键的类型,因为 union(管道)的行为与您在接口(interface)情况下所期望的不同。请参阅https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types :
If a value has the type A | B, we only know for certain that it has members that both A and B have. In this example, Bird has a member named fly. We can’t be sure whether a variable typed as Bird | Fish has a fly method. If the variable is really a Fish at runtime, then calling pet.fly() will fail
您可以通过输入一行 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;
})
}
(请注意,如果您的实际类型有更多不同类型的键,则这不合适,但您的代码无论如何都会无效。)
关于javascript - 我可以在 typescript 中使用什么来显示两个接口(interface)的值之间的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61355159/