Comparação com TypeScript
Dois sistemas de tipos com filosofias diferentes: um apaga na compilação, o outro confere também em execução.
A comparação certa não é de sintaxe — é de onde o tipo vive. O TypeScript apaga tudo antes de rodar: o tipo é um contrato entre quem escreve e quem lê, e no JSON.parse ele acaba. Em DataForge o tipo declarado é conferido também na fronteira em execução, e é por isso que ele pega o que um any mal colocado deixa passar.
A tabela#
| TypeScript | DataForge | Nota |
|---|---|---|
type Id = number | type Id := Integer | alias nos dois |
type N = number \| string | type N := Integer \| String | união nos dois |
A & B | A & B | interseção nos dois |
| branded type por convenção | opaque type Cpf := String | aqui é mecanismo, não convenção |
| — (não existe) | Integer where valor bigger 0 | refinamento conferido |
function f<T>(x: T): T | action f<T>(x: T) -> T | sem limite, nenhum dos dois cobra |
<T extends number> | <T extends Number> | cobrado nas duas metades |
interface | trait | |
readonly / as const | record | imutável por construção |
enum | enum | com método, aqui |
x?.y / x ?? y | x?.y / x ?? y | iguais |
tsc --noEmit | dataforge check | embutido, sem instalar nada |
as any | não anotar | o analisador cala, e isso é dito |
A diferença que mais aparece#
dataforge
type Positivo := Integer where valor bigger 0
action cobrar(v: Positivo) -> Integer:
yield v * 100
// Isto passa: 7 satisfaz a regra.
assert cobrar(7) is 700
// E isto e RECUSADO em execucao, nao so no editor — que e o que um
// 'as any' do TypeScript nao impede.
recusou := no
monitor:
cobrar(0 - 5)
handle Error as e:
recusou := yes
assert recusou
out "o refinamento vale onde o dado chega de fora"O que o TypeScript tem e DataForge não#
- Tipos condicionais e mapeados —
T extends U ? A : B,Partial<T>,Record<K,V>. - Inferência de fluxo tão fina quanto — o narrowing do TS por
typeofeiné mais completo. - Tipos literais de template — `
on${Capitalize<E>}`. - Ecossistema de tipos — o DefinitelyTyped não tem equivalente aqui.
O que DataForge tem e o TypeScript não#
- Refinamento conferido (
where) — no TS é convenção e uma função guarda. - Tipo opaco de verdade — o branded type do TS some na compilação.
- O tipo atravessa `adopt` — a aridade e os tipos dos parâmetros são conferidos entre arquivos, antes de rodar.
- A conferência em execução — o tipo não desaparece quando o dado vem de um JSON.