Lidar com `unknown` no TypeScript... não é uma dor de cabeça?
Olá! 👋
Sou engenheiro frontend e moro nos Países Baixos. Neste momento, também estou sofrendo com a temporada de alergias 😿
Respostas de APIs, dados de formulários, informações vindas de serviços externos...
No TypeScript, frequentemente precisamos trabalhar com valores do tipo unknown, e tratá-los corretamente pode acabar se tornando uma verdadeira dor de cabeça no dia a dia.

Sim, o unknown parece ter uma força gravitacional quase cósmica.
Mesmo assim, queremos tratar os tipos com segurança, certo?
Foi pensando nisso que criei o is-kit, uma biblioteca para criar e combinar type guards.

O que é o is-kit?
O is-kit é um toolkit leve e sem dependências para criar type guards reutilizáveis em TypeScript.
Ele ajuda você a escrever pequenas funções no estilo isFoo, combiná-las em verificações mais completas de runtime e manter o type narrowing natural dentro do fluxo normal da aplicação.
A proposta é oferecer verificações seguras, combináveis e fáceis de usar, sem obrigar você a adotar um fluxo pesado baseado em schemas.
Com o is-kit, você pode:
- Criar e reutilizar type guards tipados
- Combinar guards com
and,or,noteoneOf - Validar estruturas de objetos e coleções
- Interpretar ou verificar valores
unknownsem um grande framework de schemas
O
is-kité especialmente útil para narrowing dentro da aplicação, filtragem de dados e criação de guards reutilizáveis.
🤔 Por que usar o is-kit?
Você já se cansou de escrever as mesmas verificações isFoo repetidamente?
O is-kit pode ser uma boa escolha quando você quer:
- Criar funções
isXreutilizáveis em vez de verificações isoladas - Manter a validação em runtime leve e sem dependências
- Refinar tipos diretamente em
if,filtere outros fluxos normais do TypeScript - Combinar pequenas regras de validação
Bibliotecas como o Zod seguem uma abordagem centrada em schemas.
O is-kit, por outro lado, concentra-se no refinamento dos tipos dentro do código que você já possui.
Em vez de pensar que está “escrevendo uma validação”, você pode enxergar o is-kit como uma forma de adicionar segurança de tipos aos seus if cotidianos.
Se o Zod é especialmente útil nas fronteiras da aplicação, como APIs e inputs, o is-kit é voltado para a lógica interna da aplicação.
Um exemplo simples
Imagine que você precise verificar várias vezes se um valor é uma string com no máximo três caracteres.
Com o is-kit, você pode definir essa regra uma única vez e reutilizá-la:
import { define, isString } from "is-kit";
const isShortString = define<string>(
(value) => isString(value) && value.length <= 3,
);
Depois, basta utilizá-la normalmente:
import { isShortString } from "~/utils/is";
declare const input: unknown;
// Antes: repetimos as condições toda vez
if (typeof input === "string" && input.length <= 3) {
input.toUpperCase();
}
// Depois: reutilizamos o guard
if (isShortString(input)) {
input.toUpperCase();
}
Esse estilo funciona naturalmente com if, filter, map e outras estruturas que já fazem parte da lógica da aplicação.
🐾 Como o is-kit evoluiu
Já se passaram aproximadamente seis meses desde o lançamento da versão v1.0.
Naquela época, o is-kit começou como uma pequena biblioteca de type guards, com recursos básicos como:
defineandorstructarrayOf
Desde então, até a versão v1.6, ele evoluiu gradualmente para algo mais prático:
👉 Um toolkit para lidar com valores unknown em aplicações reais.
Vamos conhecer cinco melhorias importantes.
🪄 1. Diferenciando uma propriedade ausente de uma propriedade com valor undefined
Uma situação comum em respostas de APIs:
- Uma propriedade não existe no objeto
- A propriedade existe, mas seu valor é
undefined
Esses dois casos não são iguais.
Na versão v1.5.0, foi adicionado o optionalKey(...):
import { isString, optional, optionalKey, struct } from "is-kit";
const isUser = struct({
id: isString,
nickname: optionalKey(isString),
displayName: optionalKey(optional(isString)),
});
Isso permite representar explicitamente os dois casos.
No exemplo:
nicknamepode não existir, mas, quando existe, precisa ser uma stringdisplayNamepode não existir e também pode existir com o valorundefined
🔑 2. Narrowing baseado em propriedades com hasKey, hasKeys e narrowKeyTo
Entre as versões v1.1.13 e v1.4.0, foram adicionadas funções para trabalhar com propriedades específicas:
import {
hasKeys,
narrowKeyTo,
oneOfValues,
struct,
isString,
isNumber,
} from "is-kit";
const isUser = struct({
id: isString,
age: isNumber,
role: oneOfValues("admin", "guest", "trial"),
});
const hasRoleAndId = hasKeys("role", "id");
const byRole = narrowKeyTo(isUser, "role");
const isGuest = byRole("guest");
Isso permite criar novos guards a partir de verificações existentes, sem precisar redefinir toda a estrutura.
🧪 3. assert para validações fail-fast
O assert foi adicionado na versão v1.2.0:
import { assert, isString } from "is-kit";
declare const input: unknown;
assert(isString, input, "input must be a string");
input.toUpperCase();
Depois que o assert é executado com sucesso, o TypeScript entende que input é uma string.
Assim, também podemos usar os guards em um fluxo fail-fast quando necessário.
✨ 4. Suporte a Set e Map
Na versão v1.6.0, o is-kit recebeu suporte a estruturas como Set e Map:
import { mapOf, setOf, isString, isNumber } from "is-kit";
const isTags = setOf(isString);
const isScores = mapOf(isString, isNumber);
Nem todos os dados de uma aplicação real são arrays.
Esse suporte amplia as verificações para estruturas comuns do JavaScript.
🥏 5. Tratamento de casos especiais envolvendo números
Desde as versões v1.1.x, foram adicionados vários guards numéricos:
isIntegerisSafeIntegerisPositiveisNegativeisNaNisInfiniteNumberisZero
Eles ajudam a expressar com mais precisão o que significa um número válido em cada contexto.
Em muitos casos, verificar apenas typeof value === "number" não é suficiente.
🌟 Mais recursos
Existem várias outras funções disponíveis no is-kit.
Você pode conhecer todas elas na documentação:
🎯 Resumo
O is-kit começou como uma pequena biblioteca de type guards combináveis.
Com o tempo, ele evoluiu para:
👉 Um toolkit prático para lidar com valores unknown dentro da lógica de aplicações TypeScript.
Entre as principais melhorias estão:
- Estruturas de objetos mais expressivas com
optionalKey - Narrowing baseado em propriedades
- Assertions no estilo fail-fast
- Suporte a coleções como
SeteMap - Guards mais precisos para valores numéricos
O objetivo do is-kit é simples:
Fazer com que código type-safe também seja natural de escrever.
Caso você experimente o projeto e tenha alguma ideia ou feedback, fique à vontade para compartilhar!
Até o próximo artigo 👋
Artigo original em inglês:
https://dev.to/nyaomaru/handling-unknown-in-typescript-isnt-it-painful-4dec