Aula 43
Como Habilitar o Uso de JSX no TypeScript
Summary
Resumo da Aula sobre JSSX com TypeScript
Nesta aula, discutimos o JSSX (JavaScript XML), uma sintaxe popularizada pela biblioteca React, que permite escrever HTML-like dentro do JavaScript. O JSSX é na verdade convertido em funções JavaScript, como React.createElement
.
Principais Pontos Abordados
-
Usando JSSX no TypeScript:
- Renomear arquivos para
.tsx
. - Configurar o compilador TypeScript para habilitar JSSX no
tsc.conf.json
, usando a propriedadejsx
com valores como:preserve
: mantém o JSSX sem convertê-lo.react
: converte JSSX em chamadas deReact.createElement
.react-jsx
(oureact-native
): mantém o JSSX, mas emite arquivos.jsx
.
- Renomear arquivos para
-
Elementos Intrínsecos vs. Elementos Baseados em Valor:
- Elementos intrínsecos (como
<div>
e<span>
) são fundamentais no DOM. - Elementos baseados em valor são componentes personalizados definidos pelo usuário. Por exemplo, um componente React poderia ser usado assim:
<MeuComponente />
.
- Elementos intrínsecos (como
-
Definição e Verificação de Tipos:
- Para validar elementos intrínsecos, é necessário declarar a interface
IntrinsicElements
no namespaceJSX
. - Para elementos personalizados, você pode adicionar o tipo apropriado à interface
intrinsic elements
.
- Para validar elementos intrínsecos, é necessário declarar a interface
-
Componentes Funcionais e de Classe:
- Componente funcional:
function MeuComponente(props: { nome: string }) { return <div>{props.nome}</div>; }
- Componente de classe:
class OutroComponente extends React.Component { render() { return <MeuComponente nome="Alguém" />; } }
- Componente funcional:
-
Uso de Children:
- Para componentes que aceitam
children
, você pode definir isso na interface de props. - O
children
é uma propriedade especial e pode ser tipado como um elemento JSX ou múltiplos elementos.
- Para componentes que aceitam
Conclusão
A aula se concentrava em como escrever e validar JSSX em TypeScript, bem como a diferenciação entre elementos intrínsecos e personalizados, e a criação de componentes funcionais e de classe. A próxima aula abordará a implementação prática dos conceitos discutidos.
Video Transcript
Nesta aula nós vamos falar de JSSX.
JSSX foi popularizado no biblioteca React, uma maneira de se escrever parecido com HTML
no JavaScript, no que na verdade aquele HTML, aquele formato é convertido para JavaScript,
por exemplo a chamada da função react.createElement.
Então há uma transformação do que parece-se HTML para na verdade funções de JavaScript,
um açúcar sintático.
Então vamos falar de JSSX no TypeScript.
Então, primeira coisa que você tem que fazer é renomear o seu arquivo para .tsx, para poder usar JSSX.
Eu criei aqui um arquivo na parte de src-jsx.index.tsx,
tsc, adiciona sx para poder usar jsx dentro desse arquivo.
Agora outra coisa que você tem que fazer é habilitar a opção do copilador,
traço jsx.
Como eu estou usando tsc.conf.json, invés da linha de comando diretamente,
invés de digitar traço jsx na linha de comando,
quando executar o tsc, vou no meu tsc.conf.
Dentro da chave compare options, vou adicionar uma propriedade chamada jsx.
Agora se propriedade tem três valores, tenho preserve, e eu vou usar aqui,
esse valor preserve, ele quando passar pelo copilador, ele vai manter o formato do jsx
e não vai converter, não vai transformar para, por exemplo, chamadas do react.createElement.
Outra opção para isso é o react, e ele vai converter o jsx para chamada de react.createElement.
E tem o outro que é o react.trasunative, que ele mantém, mantém o jsx como está,
mas a extensão do arquivo emitido é .js.
E esqueci de dizer também a extensão do arquivo emitido,
se usar por exemplo vai ser .jsx quando for copilado,
no caso do react.ssonative vai ser .jsx.
Se quiser saber mais sobre isso, só olhar na documentação, no site do TypeScript,
pode documentação do test.confeg.jsx e ter que dizer nos três, preserve and react.trasunative.
Voltando aqui, aqui a gente está vazando,
vou deixar como preserve para poder preservar, manter o jsx e vai ser emitido na arquivo.jsx do tsx.
Está bom?
Vamos dar uma olhada aqui, a gente tem que saber a diferença entre intrinsic elements,
elementos intrínsecos e value based elements, elementos baseados em valor.
Vamos voltar a texta aqui.
Então, elementos intrínsecos são aqueles que são fundamentais,
por exemplo, no caso da HTML do DOM, tem div, span,
PA, e se pude antes, várias tags, são os elementos intrínsecos.
Esses elementos intrínsecos normalmente quando você chama, por exemplo,
react.elemente, ele usa o nome do elemento intrínseco entre aspas.
Agora, o intrínsecos, o elemento baseado em valor são aqueles que você define,
os customizados, é aqueles componentes que a gente faz.
Certo?
Por exemplo, class, meu componente, italextends, reactcomponent, qualquer coisa.
Então, esse componente pode ser usado da seguinte maneira,
a abrir sinal de menos, nome e fecha tag.
E esse aqui não é intrínseco porque a gente definiu,
não é fundamental, no caso do soudom, da HTML, não é uma coisa básica fundamental de lá.
Então, esse é o elemento baseado em valor.
Normalmente, quando você chama react.elemente, quando é transformado,
ele usa o meu componente sem aspas, porque esse meu componente é definido em algum outro local.
Certo?
Esse componente, elemento baseado em valor, você já sabe react,
pode ser definido com a classe, como eu defini aqui, o componente de classe.
Tem também o componente funcional, né?
Componente funcional ou de função.
O funcional antes do react.e Hooks, ele era stateless, né?
Antigamente, chamado de stateless, não tinha estado,
podia manter o estado funcional antigamente antes de react.e Hook.
Mas agora, como tem o Hook, pode adicionar estado, não pode mais chamar de stateless,
então é só funcional.
Tá, e vamos falar que...
Vamos começar a escrever um negócio aqui.
Estas são as notas.
Vou voltar para TypeScript.
Então, vamos aqui fazer o seguinte.
Estamos no arquivo tsx, eu já habitei o meu editor de test para poder pegar os erros de TypeScript na maior hora que eu digito.
Se eu se aditar alguma coisa que não faz sentido, eu já pego o erro aqui e mostro na minha,
onde eu pulmasse em cima.
Não pode encontrar esse nome porque ele dá um defini, né?
Um local.
Então, vamos supor que a gente tivesse uma propriedade intrínseca em sistema aqui.
Vamos falar de Oi.
Tá, note que não tem erro e ele acha que esse tipo é N.
Mas como a gente pode adicionar o check de tipo para elementos intrínsecos?
Bem, faz o seguinte.
Vai no namespace jsx, é o namespace que tem.
Tem um interface chamada intrinsic elements,
elementos intrínsecos, nós podemos definir o nome desse elemento lá para poder ele checkar o tipo.
Se não tiver nenhuma definição, nenhum recorde da definição da interface intrinsic elements,
TypeScript não vai checar por nada.
Por isso não deu nenhum erro aqui.
No momento que eu fazer aquela definição da interface, você vai ver que ele vai dar aí.
Então, vamos aqui.
Então, tem um interface chamada intrinsic element.
Essa interface vai estar dentro do namespace, tá?
Eu vou usar declare, declarar namespace jsx.
Eu usei declare porque o namespace já está definido, então a gente usa esse declare para poder adicionar algo a mais a algo que já existe.
O namespace jsx interface intrinsic elements, quando eu definir isso aqui, note que ele já reclamou dizendo que a propriedade Oi
não existe no tipo jsx.intrinsicElement onde jsx é o namespace.
Certo?
Para poder permitir o uso validar esse elemento intrinsic, você poderia adicionar Oi aqui e dizer que é N.
Com isso, ele não vai reclamar e já tem Oi dentro da interface intrinsic element,
tipo N. Claro que você pode especificar e, em vez de falar N, falar algo mais específico, que é sempre melhor.
Se tiver N, qual é o sentido, né?
Mas pelo menos diz que pode ter Oi e não pode ter Outros, por exemplo.
Se eu tiver essa aqui, vai dar aí porque não está na lista.
Se eu adicionar a lista, o response N vai permitir.
Agora, se eu tivesse que eu quisesse permitir qualquer nome de elemento arbitrário, é só adicionar aqui uma da seguinte maneira.
Vai ser do tipo N, mas qual vai ser o nome? Tem que dizer qualquer nome.
Como é que diz qualquer nome?
Abre os coxetes, nome do elemento. Pode ser qualquer nome aqui.
Eu digo nome do elemento, dois pontos, o tipo, vai ser string.
Desse caso ele vai permitir qualquer nome que é string.
Nem precisa desse aqui.
Está certo?
Isso é só a curiosidade aí, você definir seus próprios tipos de J, S, X.
Está certo?
Então vamos continuar e falar de outra coisa aqui.
Vamos falar de um componente de função, funcional.
Então vamos criar uma função aqui, meu componente.
Tem uma função, não é componente normalmente, você já sabe.
Eu tenho conhecimento React.
O primeiro parâmetro seria as próprias, né?
Mas a gente está usando TypeScript, então normalmente o que você vai seguir fazendo é o seguinte.
Tem que definir qual é o tipo de prop.
Então você pode definir aqui, por exemplo, componente leva nome que é uma string.
Aí você vai aqui e retorna qualquer coisa aqui, sei lá.
Pode ser retorna...
...
... e ponho o nome aqui.
Bem, eu não tenho a declaração nenhum namespace para DOM de HTML, por isso que ele não reclamou, mas se eu tivesse...
... pegar isso aqui sem esse nome de elemento, ele daria problema, tá?
...
Agora normalmente quando você estiver desenvolvendo aí, alguém já escreveu esses tipos para React.
A gente vai ver depois que já está escrito e você não precisa se preocupar em fazer o seu próprio...
... declaração da interface aqui.
Vamos supor que alguém já escreveu que quer div.
Então eu vou estar aqui adicionando.
Então você pode pôr aqui já de literal objeto, essa declaração aqui literal.
Ou você pode, que eu normalmente feito, extrair esse cara, seu objeto em uma interface.
Então interface meu componente, sei lá, props, ou pode chamar props, qualquer nome que você quiser.
Se dá essa interface, eu pego aqui, eu corto...
... e eu falo que o props vai ser meu componente props.
Tá certo?
Props, e eu esqueci de falar props aqui.
Props.nome.
Então poderia usar esse componente em qualquer outro local.
Vamos escrever aqui, sei lá...
Function, outro componente.
Vamos fazer de...
... de class, a gente fez funcional, vamos falar de class.
Class, outro componente.
Mas como é que faz em class?
Vamos ver aqui, vamos dizer que esse class tem essa função chamada render.
Do render a gente retorna o meu componente.
Vamos dizer meu componente, qual vai ser as props, né?
Vai ser nome, então nome é alguém.
Dessa maneira aqui.
Certo?
E eu poderia usar em qualquer local outro componente.
E ele iria criar esse cara aqui.
E claro que eu estou...
... propondo que você está usando React, por isso que estou usando render, mas poderia ser qualquer outra maneira.
Outra coisa que também é valor de retorno.
Está a função, nesse caso, do function component ou do render.
Qual é o valor de retorno?
Normalmente quando você trabalhar, por exemplo, com React e TypeScript, o valor de retorno vai ser Jsx.element.
Se você retornar só um só elemento.
Nesse caso, como só retornar só um só elemento, essa função, na verdade, vai retornar se a gente definir explicitamente.
Esse Jsx element.
É claro que ele não tem elemento, porque isso foi escrito por alguém em um pacote, certo?
A gente não tem, a gente teria que definir isso.
Eu vou mostrar já, depois, quando a gente for criar um aplicativo de React, usando o template do TypeScript, como eles se usam aqui.
Nesse caso, retornando o meu nome é N, porque essa div aqui é N.
Poderia ser outra coisa, Jsx, element, essas coisas.
Nesse caso, quando você pega o componente aqui, vamos ver.
Eu teria que definir o elemento em algum lugar aqui, na interface Jsx.
Ah, sei lá, vamos ver se funciona se eu definir interface element.
Então, meu componente retorna Jsx element, porque o div foi definido como Jsx element.
Então, mesmo que já foi definido em algum lugar, por isso eu adicionei que isso é para fazer...
Imaginar que é uma caixa preta.
Então, normalmente, você vai retornar as pós...
Se for múltiplos, seria a array de Jsx element, ou se fosse string, ou qualquer coisa diferente.
A maioria das coisas que você fizer com TypeScript, por exemplo, no React,
vai envolver o Jsx.algum coisa como o tipo.
Porque Jsx é o namespace, tá?
Tá certo? Então...
Outra coisa que você vai ver também, se você quiser definir...
Por exemplo, se eu definir esse componente aqui, function, componente com children, props...
Se esse componente retornasse, sei lá, um div, mais que pegasse o children que vem do...
Por exemplo, componente com children.
Você pega esse componente, mas você não vai fechar na mesma hora, você vai abrir e vai por outra coisa,
passando isso como children.
Componente com children.
Não tem h2 que não existe lá na definição, posso adicionar h1, desculpa.
E com isso, esse componente, a instância recebe children, né?
Filhos ou filhos.
E isso vai parecer na variável props.ch.
Você também pode checar se esse valor do children está certo.
Isto é.
Se eu tiver o componente com children no props aqui, eu vou falar...
Criar um interface aqui, props.
Nessa interface, eu posso definir qual o tipo do children.
Props.
Tá? Children.
Eu posso, por exemplo, nesse caso, é um Jpsx, ela.
Então, posso definir que o children tem que ser um único elemento de Jpsx.
Ah, o que aconteceu?
Nossa.
Tipo, não sei o que.
Props.
Children não tem no tipo vazio.
Hum, vazio componente com children vazio.
Aí.
Deixa eu ver, eu acho que ele está pensando que o children é propriedade daqui.
Vamos ver.
É.
Então, quando a gente vê já, já na prática, isso vai funcionar.
O problema é que ele está pensando que o children é, na verdade, como passado normalmente, como se fosse espécie de atributo.
Mas a gente vai ver que é uma propriedade especial.
Então, ele iria dar tudo certo aqui, mas ele iria reclamar se eu passasse outra coisa aqui com o string.
Tá?
Então, vamos ver isso.
Próximo aula, na aula de prática, tá bom?
Por essa aula só e até a próxima.
Nenhum comentário ainda (loading...)
Nenhum comentário ainda (loading...)
Gostou da aula? 😆👍
Apoie nosso trabalho com uma doação: