Pular para o conteúdo principal

TypeGuard

O TypeGuard e a classe central para verificacao de tipos em tempo de execucao. Ele substitui completamente o uso manual de typeof, instanceof e verificacoes ad-hoc no projeto.

Regra do projeto: nunca use typeof diretamente para validacao de tipos primitivos. Use sempre TypeGuard.

import { TypeGuard } from "tyforge";

Verificacao de tipos

Todos os metodos de verificacao recebem (value: unknown, fieldPath: string) e retornam Result<true, ExceptionValidation>. A excecao e isString, que retorna Result<string, ExceptionValidation> com o valor ja trimado.

isString

Verifica se o valor e uma string, aplica trim() e valida comprimento.

static isString(
value: unknown,
fieldPath: string,
min?: number, // padrao: 1
max?: number, // padrao: Number.MAX_SAFE_INTEGER
): Result<string, ExceptionValidation>

Retorna a string trimada no campo value em caso de sucesso:

const result = TypeGuard.isString(input, "name", 1, 100);
if (result.success) {
const trimmed: string = result.value; // string ja sem espacos extras
}

isNumber

Verifica se o valor e um numero valido (nao NaN), com limites opcionais e precisao decimal.

static isNumber(
value: unknown,
fieldPath: string,
min?: number, // padrao: Number.MIN_SAFE_INTEGER
max?: number, // padrao: Number.MAX_SAFE_INTEGER
decimalPrecision?: number, // padrao: Infinity
): Result<true, ExceptionValidation>
const result = TypeGuard.isNumber(price, "price", 0, 99999, 2);

isInteger

Verifica se o valor e um inteiro (Number.isInteger), com limites opcionais. Delega para isNumber com decimalPrecision = 0.

static isInteger(
value: unknown,
fieldPath: string,
min?: number,
max?: number,
): Result<true, ExceptionValidation>

isPositiveInteger / isNegativeInteger

Atalhos para isInteger com limites pre-definidos:

TypeGuard.isPositiveInteger(value, "count");   // min = 0
TypeGuard.isNegativeInteger(value, "offset"); // max = -1

isPositiveNumber / isNegativeNumber

Atalhos para isNumber com limites pre-definidos e precisao decimal opcional:

TypeGuard.isPositiveNumber(value, "amount", 2); // min = 0, decimalPrecision = 2
TypeGuard.isNegativeNumber(value, "debt", 2); // max = -MIN_VALUE

isBoolean

Verifica se o valor e um booleano (typeof value === "boolean").

static isBoolean(value: unknown, fieldPath: string): Result<true, ExceptionValidation>

isObject

Verifica se o valor e um objeto nao-nulo e nao-array.

static isObject(value: unknown, fieldPath: string): Result<true, ExceptionValidation>

isArray

Verifica se o valor e um array com limites opcionais de tamanho.

static isArray(
value: unknown,
fieldPath: string,
min?: number, // padrao: 0
max?: number, // padrao: Number.MAX_SAFE_INTEGER
): Result<true, ExceptionValidation>

isDate

Verifica se o valor e uma instancia de Date valida (!isNaN(date.getTime())).

static isDate(value: unknown, fieldPath: string): Result<true, ExceptionValidation>

isFunction

Verifica se o valor e uma funcao.

static isFunction(value: unknown, fieldPath: string): Result<true, ExceptionValidation>

isNull / isUndefined

Verificam se o valor e exatamente null ou undefined.

static isNull(value: unknown, fieldPath: string): Result<true, ExceptionValidation>
static isUndefined(value: unknown, fieldPath: string): Result<true, ExceptionValidation>

isRegExp / isSymbol / isBigInt / isSet / isMap

Verificacoes para tipos especializados:

static isRegExp(value: unknown, fieldPath: string): Result<true, ExceptionValidation>
static isSymbol(value: unknown, fieldPath: string): Result<true, ExceptionValidation>
static isBigInt(value: unknown, fieldPath: string): Result<true, ExceptionValidation>
static isSet(value: unknown, fieldPath: string): Result<true, ExceptionValidation>
static isMap(value: unknown, fieldPath: string): Result<true, ExceptionValidation>

Type narrowing

Metodos que funcionam como type guards nativos do TypeScript (retornam boolean com narrowing):

isRecord

Verifica se o valor e um Record<string, unknown>. Funciona como type guard para narrowing:

static isRecord(value: unknown): value is Record<string, unknown>
if (TypeGuard.isRecord(data)) {
// TypeScript sabe que data e Record<string, unknown>
const name = data["name"];
}

isCallable

Verifica se o valor e uma funcao. Funciona como type guard:

static isCallable(value: unknown): value is Function
if (TypeGuard.isCallable(handler)) {
handler(); // TypeScript sabe que handler e Function
}

Extracao de valores

Metodos que retornam Result<T, ExceptionValidation> com o valor tipado, nao apenas Result<true>. Uteis quando voce precisa do valor extraido apos a validacao.

extractBoolean

Extrai um booleano, retornando o valor tipado:

static extractBoolean(value: unknown, fieldPath: string): Result<boolean, ExceptionValidation>
const result = TypeGuard.extractBoolean(input, "active");
if (result.success) {
const active: boolean = result.value;
}

extractArray

Extrai um array com limites opcionais de tamanho:

static extractArray(
value: unknown,
fieldPath: string,
min?: number,
max?: number,
): Result<unknown[], ExceptionValidation>
const result = TypeGuard.extractArray(input, "tags", 1, 10);
if (result.success) {
const tags: unknown[] = result.value;
}

extractNumber

Extrai um numero com limites opcionais:

static extractNumber(
value: unknown,
fieldPath: string,
min?: number,
max?: number,
): Result<number, ExceptionValidation>
const result = TypeGuard.extractNumber(input, "age", 0, 150);
if (result.success) {
const age: number = result.value;
}

Validacao de enum

isEnumKey

Verifica se um valor e uma chave valida de um objeto enum:

static isEnumKey<T extends object>(
enumObj: T,
value: string | number,
fieldPath: string,
): Result<true, ExceptionValidation>
const OStatus = { ACTIVE: "active", INACTIVE: "inactive" } as const;

TypeGuard.isEnumKey(OStatus, "ACTIVE", "status"); // ok(true)
TypeGuard.isEnumKey(OStatus, "active", "status"); // err(...)

isEnumValue

Verifica se um valor e um valor valido de um objeto enum:

static isEnumValue<T extends object>(
enumObj: T,
value: string | number,
fieldPath: string,
): Result<true, ExceptionValidation>
const OStatus = { ACTIVE: "active", INACTIVE: "inactive" } as const;

TypeGuard.isEnumValue(OStatus, "active", "status"); // ok(true)
TypeGuard.isEnumValue(OStatus, "ACTIVE", "status"); // err(...)

Utilitarios

isEmpty

Verifica se um valor esta "vazio". Suporta multiplos tipos:

static isEmpty(value: unknown): boolean
TipoConsiderado vazio
null, undefinedSempre
stringApos trim(), se o comprimento for 0
ArraySe length === 0
Set, MapSe size === 0
objectSe nao possui chaves proprias
TypeGuard.isEmpty(null);        // true
TypeGuard.isEmpty(""); // true
TypeGuard.isEmpty(" "); // true
TypeGuard.isEmpty([]); // true
TypeGuard.isEmpty({}); // true
TypeGuard.isEmpty(new Set()); // true
TypeGuard.isEmpty("hello"); // false
TypeGuard.isEmpty([1]); // false

isHex

Verifica se o valor e um hexadecimal com prefixo 0x, com comprimento de digitos util opcional:

static isHex(
value: unknown,
fieldPath: string,
length?: number, // digitos uteis (sem contar "0x")
): Result<true, ExceptionValidation>
TypeGuard.isHex("0x1a2b", "hash");         // ok(true)
TypeGuard.isHex("0x1a2b", "hash", 4); // ok(true) — 4 digitos
TypeGuard.isHex("0x1a2b", "hash", 8); // err(...) — esperava 8
TypeGuard.isHex("hello", "hash"); // err(...)

Resumo de assinaturas

MetodoRetornoDescricao
isStringResult<string>String trimada com limites de comprimento
isNumberResult<true>Numero com faixa e precisao decimal
isIntegerResult<true>Inteiro com faixa
isPositiveIntegerResult<true>Inteiro positivo ou zero
isNegativeIntegerResult<true>Inteiro negativo
isPositiveNumberResult<true>Numero positivo ou zero com precisao
isNegativeNumberResult<true>Numero negativo com precisao
isBooleanResult<true>Booleano
isObjectResult<true>Objeto nao-nulo, nao-array
isArrayResult<true>Array com limites de tamanho
isDateResult<true>Date valido
isFunctionResult<true>Funcao
isNullResult<true>Exatamente null
isUndefinedResult<true>Exatamente undefined
isRegExpResult<true>Expressao regular
isSymbolResult<true>Symbol
isBigIntResult<true>BigInt
isSetResult<true>Set
isMapResult<true>Map
isRecordvalue is RecordType guard para Record
isCallablevalue is FunctionType guard para Function
extractBooleanResult<boolean>Extrai booleano tipado
extractArrayResult<unknown[]>Extrai array tipado
extractNumberResult<number>Extrai numero tipado
isEnumKeyResult<true>Chave de enum
isEnumValueResult<true>Valor de enum
isEmptybooleanVerificacao de vazio
isHexResult<true>Hexadecimal com prefixo 0x