Typescript 定义索引签名与扩展接口之间的冲突

Typescript 定义索引签名与扩展接口之间的冲突,typescript,Typescript,我有两个界面,human和bird。如您所见,human中的所有内容都包装在value\u human键中。鸟也一样 interface human{ _human: { hands: number, name:string } } interface bird{ _bird: { wings: number, name:number } } interface IEntity extends h

我有两个界面,
human
bird
。如您所见,
human
中的所有内容都包装在value
\u human
键中。鸟也一样

interface human{
    _human: {
        hands: number,
        name:string
    }
}

interface bird{
    _bird: {
        wings: number,
        name:number
    }
}

interface IEntity extends human, bird{ }

function foo(x: IEntity) {
    let keys = Object.keys(x);
    console.log(x[keys[0]].name);
}
要访问其内容,请在函数
foo
中执行以下操作:

let keys = Object.keys(x);
x[keys[0]].name
但我得到了一个错误:
元素隐式地具有任何类型,但没有索引签名。
为了解决这个问题,如果我用
[key:string]
各自的接口替换键
bird
human
,我会得到以下错误:

Property 'human' of type '{ hands: number; name: string; }' is not assignable to string index type '{ wings: number; name: number; }'.

我想知道除了在
tsconfig
中创建不报告隐式错误的标志之外,是否还有其他解决方法。问题是
Object.keys
的返回是
string[]
,当您尝试使用字符串索引访问
IEntity
时,您会看到错误。您可以通过告诉typescript,
键的类型不是
字符串[]
,而是更具体的类型
(keyof IEntity)[
,来解决这个问题

以你为例:

function foo(x: IEntity) {
    let keys = Object.keys(x) as (keyof IEntity)[]; // Note the cast here
    console.log(x[keys[0]].name); // x[keys[0]].name is inferred as string|number, no errors
}

问题是
Object.keys
的返回值是
string[]
,当您尝试使用字符串索引访问
属性时,您会看到错误。您可以通过告诉typescript,
键的类型不是
字符串[]
,而是更具体的类型
(keyof IEntity)[
,来解决这个问题

以你为例:

function foo(x: IEntity) {
    let keys = Object.keys(x) as (keyof IEntity)[]; // Note the cast here
    console.log(x[keys[0]].name); // x[keys[0]].name is inferred as string|number, no errors
}

谢谢但同样的逻辑不适用于
类型IEntity=human | bird
。你能解释一下为什么吗?
type IEntity=human | bird
interface IEntity扩展human,bird{}
不同。但是
人和鸟
是一样的。它不适用于union情况,因为union类型的键是两个类型之间的共享键集。由于这些类型没有共同的键,
keyof(human | bird)
最终成为
never
。谢谢。但同样的逻辑不适用于
类型IEntity=human | bird
。你能解释一下为什么吗?
type IEntity=human | bird
interface IEntity扩展human,bird{}
不同。但是
人和鸟
是一样的。它不适用于union情况,因为union类型的键是两个类型之间的共享键集。由于这些类型没有共同的键,
keyof(human | bird)
最终成为
never