Подпись индекса смешанного типа Typescript с известными свойствами

Aug 15 2020

Допустим, у интерфейса есть некоторые известные свойства с их типами и могут быть дополнительные с неизвестными ключами и некоторыми другими типами . что-то вроде:

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

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

Ошибка TS: «Свойство 'lenght' типа 'number' не может быть присвоено строковому индексу с типом 'string'."

Как набрать такой интерфейс?

Ответы

3 Eldar Aug 15 2020 at 20:03

[key: string]: string;это предотвращает отсутствие в Fooинтерфейсе строковых свойств. (В вашем примере номер).

Что вы можете сделать, так это разделить известные и неизвестные свойства на два интерфейса и определить целевой тип как тип объединения, как показано ниже:

interface Foo {      
  lenght: number;
}

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

type FooBar = Foo | Bar;

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

Ссылка на игровую площадку

1 MohamedAllal Oct 18 2020 at 17:16

Посмотрите этот фрагмент, он хорошо объясняет суть

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

Для этого элемента

Наличие как строкового, так и числового индексаторов.
Это не обычный вариант использования, но компилятор TypeScript, тем не менее, его поддерживает. Однако у него есть ограничение: индексатор строк более строгий, чем индексатор чисел. Это сделано намеренно, например, чтобы можно было вводить такие вещи, как: