Texto datilografado mistura assinatura de índice com propriedades conhecidas

Aug 15 2020

Digamos que a interface tenha algumas propriedades conhecidas com seus tipos e pode ter propriedades adicionais com chaves desconhecidas e alguns outros tipos . algo como:

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

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

Erro de TS: "A propriedade 'comprimento' do tipo 'número' não pode ser atribuída ao tipo de índice de string 'string'."

Como essa interface deve ser digitada?

Respostas

3 Eldar Aug 15 2020 at 20:03

[key: string]: string;isso evita que a Foointerface não tenha nenhuma propriedade de string. (Em seu número de exemplo).

O que você pode fazer é separar as propriedades conhecidas e desconhecidas em duas interfaces e definir seu tipo de destino como um tipo de união como a seguir:

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
};

Link Playground

1 MohamedAllal Oct 18 2020 at 17:16

Confira este snippet para explicar bem o ponto

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;
}

Você pode verificar este artigo para mais detalhes (eu escolhi o snippet de lá)

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

Para este elemento

Ter indexadores de string e número
Este não é um caso de uso comum, mas o compilador TypeScript oferece suporte a ele mesmo assim. No entanto, ele tem a restrição de que o indexador de string é mais rígido do que o indexador de número. Isso é intencional, por exemplo, para permitir a digitação de coisas como: