如何将索引签名与已知属性混合?

How to mix index signature with known properties?

假设接口有一些已知的属性和它们的类型,并且可以有额外的未知键和一些其他类型,比如:

interface Foo {
  length: number;
  [key: string]: string;
}

const foo : Foo = {
  length: 1,
  txt: "TXT",
};

TS 错误:

Property 'length' of type 'number' is not assignable to string index type 'string'.

这样的界面应该怎么打?

[key: string]: string; 这会阻止 Foo 接口具有 none 字符串属性(在您的示例中,number)。

您可以做的是在两个接口中分离已知和未知属性,并将您的目标类型定义为联合类型,如下所示:

interface Foo {      
  length: number;
}

interface Bar {
    [key: string]: string ;
}

type FooBar = Foo | Bar;

const foo : FooBar = {
  length: 1, // its ok defined in foo
  txt: "TXT", // string is ok
  baz : 3 // error because its not string
};

Playground Link

看看这个片段,它很好地解释了这一点

interface ArrStr {
  [key: string]: string | number; // Must accommodate all members

  [index: number]: string; // Can be a subset of string indexer

  // Just an example member
  length: number;
}

您可以查看这篇文章了解更多详情(我从那里摘取了片段)

https://basarat.gitbook.io/typescript/type-system/index-signatures

对于这个元素

Having both string and number indexers
This is not a common use case, but TypeScript compiler supports it nonetheless. However, it has the restriction that the string indexer is more strict than the number indexer. This is intentional e.g. to allow typing stuff like: