Como Usar Autocomplete em TypeScript com Tipos Literais e Strings Arbitrárias
Tags: react, typescript, programming, productivity
Published: 2024-07-04 13:17:29

No desenvolvimento de aplicações com TypeScript, é comum definir tipos específicos para propriedades, garantindo que apenas valores válidos sejam usados. No entanto, pode haver casos em que você deseja ter suporte ao autocomplete para valores pré-definidos e, ao mesmo tempo, permitir a inserção de qualquer string. Neste artigo, vamos explorar como combinar tipos literais e strings em TypeScript para resolver essa necessidade, oferecendo uma solução flexível e robusta.

### Problema

Imagine que você está desenvolvendo um sistema de ícones para uma aplicação. Você tem um conjunto de ícones padrão, como "add" e "delete", mas também deseja permitir que os desenvolvedores possam usar ícones personalizados que não estão previamente definidos. A solução deve oferecer:

1. **Autocomplete para valores padrão**: Facilitar a vida dos desenvolvedores com sugestões de valores válidos durante a codificação.
2. **Flexibilidade para valores personalizados**: Permitir a inserção de qualquer string como nome de ícone, sem restrições.

### Solução

A solução para este problema é combinar tipos literais e strings arbitrárias em TypeScript. Veja como fazer isso:

#### Passo 1: Defina o Tipo `TIcon`

Primeiro, definimos um tipo que combina valores literais específicos e qualquer string.

```typescript
type TIcon = "add" | "delete" | (string & {});
```

#### Passo 2: Utilização no Código

Vamos usar este tipo em um componente React para exemplificar seu uso.

```typescript
interface IconProps {
  icon: TIcon;
}

const IconComponent: React.FC<IconProps> = ({ icon }) => {
  return <span>{icon}</span>;
};

// Exemplos de uso com autocomplete e strings arbitrárias
const App: React.FC = () => {
  return (
    <div>
      <IconComponent icon="add" />
      <IconComponent icon="delete" />
      <IconComponent icon="customIcon" />  // Permite qualquer string
    </div>
  );
};

export default App;
```

### Explicação do Código

1. **Tipo `TIcon`**:
   - O tipo `TIcon` é definido como uma união que inclui os valores literais "add" e "delete", além de qualquer string (`string & {}`).

2. **Interface `IconProps`**:
   - Define as propriedades esperadas pelo componente `IconComponent`, usando o tipo `TIcon` para a propriedade `icon`.

3. **Componente `IconComponent`**:
   - Um simples componente que recebe a propriedade `icon` e a exibe.

4. **Exemplos de Uso**:
   - Ao usar `IconComponent`, você obtém autocomplete para "add" e "delete" no TypeScript, mas ainda pode passar qualquer string como valor.



![demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4c4y3mut80au2pf2lhm.png)



### Benefícios

- **Autocomplete**: Durante o desenvolvimento, o TypeScript fornecerá sugestões para os valores literais definidos.
- **Flexibilidade**: Ainda é possível usar qualquer string como valor, oferecendo flexibilidade para casos não previstos inicialmente.
- **Tipagem Forte**: Mantém a tipagem forte do TypeScript, ajudando a prevenir erros e a melhorar a experiência de desenvolvimento.

### Problema Resolvido

Um exemplo prático de onde essa solução pode ser extremamente útil é em sistemas de design com ícones. Muitas vezes, uma aplicação tem um conjunto de ícones padrão, mas também precisa ser flexível o suficiente para permitir ícones personalizados fornecidos pelo usuário ou por designers.

Imagine que você tem uma aplicação de design onde os usuários podem escolher ícones para seus projetos. Você fornece um conjunto de ícones padrão, mas os usuários podem carregar seus próprios ícones personalizados. Com a abordagem acima, você pode oferecer um autocomplete para os ícones padrão, facilitando a seleção, e ao mesmo tempo permitir que os usuários insiram qualquer string para ícones personalizados.

### Conclusão

Ao combinar tipos literais e strings arbitrárias em TypeScript, você pode criar uma solução que oferece o melhor dos dois mundos: suporte ao autocomplete para valores padrão durante o desenvolvimento e a flexibilidade de aceitar qualquer string como valor. Isso melhora a experiência do desenvolvedor, aumenta a produtividade e mantém a flexibilidade necessária para acomodar casos de uso personalizados.