Solução 01
Se você quiser ver a diff da solução, acesse esse link
Transformando o componente QuoteCard
em um componente TS
O primeiro passo é transformar o componente em um componente typescript. Como nosso projeto inteiro já está configurado como um projeto typescript, precisamos apenas mudar a extensão do arquivo para .tsx
.
Tipando a prop recebida
Assim que a extensão é alterada um erro já aparece na tela (se você não enxergou, só rodar npx tsc
para rodar o type-checking do typescript):
Esse erro ocorre porque o typescript não gosta de any implícito - se você não disser qual é o tipo dessa prop, ele irá inferir um any
. E sempre devemos tentar evitar any
s em nosso já que eles não trazem informações e deixam nossa base de código mais frágil.
Aqui temos já uma decisão a fazer: como tipar essa prop?
Tipando inline
A solução mais rápida e direta é tiparmos as props diretamente no parâmetro da função do componente. Podemos dar um console.log
e ver que um quote
é feito de author
, id
e quote
.
Tipando na origem
O certo mesmo é “escavarmos” até a origem desses dados e tentar tipar-los lá. Se formos ver, o componente App
chama a função fetchQuote
.
Vamos abrir o arquivo src/lib/services.ts
e tipar o objeto quote
diretamente na função fetchQuote()
:
Tipando a Prop
Pronto, agora que o quote
já está devidamente tipado (coloque o mouse em cima da variável quote
dentro do componente App.js
para verificar), vamos tipar inline no componente QuoteCard.tsx
.
Para entender o código acima, pense que estamos tipando o parâmetro props
da função QuoteCard
. Sabemos que o parâmetro props é um objeto que quase sempre é desestruturado. Então o tipo que vamos utilizar é:
- Um objeto (referindo-se a
props
) - Esse objeto possui a chave quote (referindo-se à prop
quote
) - Quote é um outro objeto com as chaves
author
,quote
, eid
.
Em alguns casos tipar inline é a opção mais rápida e prática. Mas pode tornar nossos componentes difíceis de serem lidos. Por isso vamos optar por tipar de outra forma.
Extraindo o tipo Quote
para um arquivo à parte
Antes de vermos outras duas formas de tiparmos props, já que estamos usando o tipo Quote
em dois lugares diferentes, vamos extraí-lo para um arquivo à parte e adicionar o código:
Vamos criar o arquivo src/lib/types.ts
Agora vamos importá-lo tanto no arquivo src/lib/services.ts
como no componente App.tsx
.
Tipando com interface
Tipamos de forma inline as props, mas poderíamos fazer isso com interface:
Tipando com type
Da mesma forma, poderíamos fazer com um type alias
Type Alias ou Interface?
Essa provavelmente é a pergunta mais formulada no universo Typescript e a resposta é: qualquer um! Existem algumas pequenas diferenças (que provavelmente não definirão a escolha) entre as duas formas, mas basicamente é uma questão de escolha.
Eu particularmente uso type alias pela versatilidade em criar tipos que vão além de objetos. Mas é uma preferência pessoal.
Transformando o componente App em componente TS
Vamos para a segunda parte da questão, que é transformarmos o App.jsx
em App.tsx
.
O primeiro erro que aparece é:
Isso ocorre porque o useState
não sabe exatamente qual é o formato do estado quote
, já que ele é inicializado com undefined
.
Vamos ver mais para frente como fazer isso, mas por enquanto vamos inicializar um objeto com as propriedades vazias no useState
Um outro erro ainda vai persistir que é o de resolver as importações. Para isso precisamos
- Arrumar as importações no
main.jsx
- Transformar o
main.jsx
emmain.tsx
- Ajustar importações no
index.html
- Adicionar um “non null assertion” no
main.tsx