Tipos na desestruturação de objetos

122

este

const { foo: IFoo[] } = bar;

e isto

const { foo: Array<IFoo> } = bar;

irá causar razoavelmente um erro.

E isto

const { foo: TFoo } = bar;

irá apenas destruir a TFoopropriedade.

Como os tipos podem ser especificados para propriedades de objetos desestruturados?

Estus Flask
fonte
Boa pergunta, mas não será capaz de inferir o tipo a partir da definição de barmesmo assim?
2
Isso é coberto muito bem aqui .
O comentário @ user663031 deve ser removido, pois é enganoso.
Sasuke Uchiha
@SasukeUchiha O artigo não está disponível, mas a maioria dos artigos pode ser pesquisada pelo título do artigo. Ele foi movido para mariusschulz.com/blog/… . Ele lança alguma luz, de fato.
Estus Flask
Isso é útil. Obrigado.
Sasuke Uchiha

Respostas:

189

Acontece que é possível especificar o tipo depois :para todo o padrão de desestruturação:

const {foo}: {foo: IFoo[]} = bar;

O que na realidade não é melhor do que o velho

const foo: IFoo[] = bar.foo;
Artem
fonte
2
Mas {foo}não é um valor. É o que geralmente é chamado de "padrão de atribuição de desconstrução". O que você está vendo aqui é na verdade um recurso TypeScript especial que permite que tipos sejam associados a tais padrões.
Na verdade, é mais como um caso especial, especialmente em comparação com o let x, y, z: stringqual aparentemente especifica o tipo zapenas para . Eu atualizei a resposta.
artem
55

Estou um pouco atrasado para a festa, mas:

interface User {
  name: string;
  age: number;
}

const obj: any = { name: 'Johnny', age: 25 };
const { name, age }: User = obj;

Os tipos de propriedades namee agedevem ser inferidos corretamente para stringe numberrespectivamente.

Stephen Paul
fonte
9
É um caso raro em que você gostaria de usar uma interface para cada destruição.
RA.
2

Uma continuação da minha própria pergunta.

Os tipos não precisam ser especificados para as propriedades do objeto porque são inferidos do objeto desestruturado.

Considerando que barfoi digitado corretamente, o footipo será inferido:

const bar = { foo: [fooValue], ... }; // bar type is { foo: IFoo[], ... }
...
const { foo } = bar; // foo type is IFoo[]

Mesmo se barnão foi digitado corretamente ( anyou unknown), seu tipo pode ser afirmado:

const { foo } = bar as { foo: IFoo[] }; // foo type is IFoo[]
Estus Flask
fonte