Vamos mergulhar.

Definir tipos em useState

o useState O hook permite gerenciar o estado em seu aplicativo React. É o equivalente a this.state em um componente de classe.

import * as React from "react";export const App: React.FC = () => { const [counter, setCounter] = React.useState<number>(0)  return (    <div className="App">      <h1>Result: { counter }</h1>      <button onClick={() => setCounter(counter + 1)}>+</button>      <button onClick={() => setCounter(counter - 1)}>-</button>    </div>  );}

Para definir tipos no useState gancho, você precisa passar para <> o tipo do estado. Você também pode usar um tipo de união como este <number | null> se você não tiver um estado inicial.

Definir tipos em usoRef

o useRef hook retorna um objeto ref mutável que permite acessar elementos DOM.

import * as React from "react";export const App: React.FC = () => {  const myRef = React.useRef<HTMLElement | null>(null)  return (    <main className="App" ref={myRef}>      <h1>My title</h1>    </main>  );}

Como você pode ver, o caminho useRef recebe tipos é o mesmo que o useState gancho. Você só precisa passar para o <>. E, se você tiver várias anotações de tipo, use o tipo de união como eu faço aqui.

Definir tipos em useContext

useContext é um gancho que permite acessar e consumir um determinado contexto em um aplicativo React.

import * as React from "react";interface IArticle {  id: number  title: string}const ArticleContext = React.createContext<IArticle[] | []>([]);const ArticleProvider: React.FC<React.ReactNode> = ({ children }) => {  const [articles, setArticles] = React.useState<IArticle[] | []>([    { id: 1, title: "post 1" },    { id: 2, title: "post 2" }  ]);  return (    <ArticleContext.Provider value={{ articles }}>      {children}    </ArticleContext.Provider>  );}const ShowArticles: React.FC = () => {  const { articles } = React.useContext<IArticle[]>(ArticleContext);  return (    <div>      {articles.map((article: IArticle) => (        <p key={article.id}>{article.title}</p>      ))}    </div>  );};export const App: React.FC = () => {  return (    <ArticleProvider>      <h1>My title</h1>      <ShowArticles />    </ArticleProvider>  );}

Aqui, começamos criando o IArticle interface que é o tipo do nosso contexto.
Em seguida, usamos no createContext() método para criar um novo contexto e, em seguida, inicialize-o com []. Você também pode usar null como um estado inicial, se desejar.

Com isso, agora podemos lidar com o estado do contexto e definir o tipo como useContext para esperar uma matriz do tipo IArticle como um valor.

Definir tipos em uso

o useReducer hook ajuda a gerenciar estados mais complexos. É uma alternativa para useState – mas lembre-se de que eles são diferentes.

import * as React from "react";enum ActionType {  INCREMENT_COUNTER = "INCREMENT_COUNTER",  DECREMENT_COUNTER = "DECREMENT_COUNTER"}interface IReducer {  type: ActionType;  count: number;}interface ICounter {  result: number;}const initialState: ICounter = {  result: 0};const countValue: number = 1;const reducer: React.Reducer<ICounter, IReducer> = (state, action) => {  switch (action.type) {    case ActionType.INCREMENT_COUNTER:      return { result: state.result + action.count };    case ActionType.DECREMENT_COUNTER:      return { result: state.result - action.count };    default:      return state;  }};export default function App() {  const [state, dispatch] = React.useReducer<React.Reducer<ICounter, IReducer>>(    reducer,    initialState  );  return (    <div className="App">      <h1>Result: {state.result}</h1>      <button        onClick={() =>          dispatch({ type: ActionType.INCREMENT_COUNTER, count: countValue })        }> +      </button>      <button        onClick={() =>          dispatch({ type: ActionType.DECREMENT_COUNTER, count: countValue })        }> -      </button>    </div>  );}

Aqui, começamos declarando os tipos de ação que permitem manipular o contador. Em seguida, definimos dois tipos para a função redutora e o estado do contador, respectivamente.

O redutor espera uma state do tipo ICounter e um action do tipo IReducer. Com isso, o contador agora pode ser manipulado.

o useReducer gancho recebe a função redutora e um estado inicial como argumentos e retorna dois elementos: o state do balcão e do dispatch açao.

Para definir o tipo para os valores retornados por ueReducer, basta passar para o <> o tipo de seus dados.

Com isso, o contador agora pode ser incrementado ou diminuído por meio de useReducer.

Definir tipos em useMemo

o useMemo O gancho permite memorizar a saída de uma determinada função. Retorna um valor memorizado.

const memoizedValue = React.useMemo<string>(() => {  computeExpensiveValue(a, b)}, [a, b])

Para definir tipos em useMemo, basta passar para o <> o tipo de dados que você deseja memorizar. Aqui, o gancho espera um string como um valor retornado.

Definir tipos em uso

o useCallback O gancho permite memorizar uma função para evitar renderizações desnecessárias. Retorna um retorno de chamada memorizado.

type CallbackType = (...args: string[]) => voidconst memoizedCallback = React.useCallback<CallbackType>(() => {    doSomething(a, b);  }, [a, b]);

Aqui, declaramos o CallbackType tipo que está usando como tipo no retorno de chamada que queremos memorizar.

Ele espera receber parâmetros do tipo string e deve retornar um valor do tipo void.

Em seguida, definimos esse tipo como useCallback – e se você passar um tipo errado para o retorno de chamada ou a matriz de dependências, o TypeScript gritará com você.

Você pode encontrar outros ótimos conteúdos como este em meu blog ou me siga no Twitter para ser notificado.

Obrigado pela leitura.