Types Are for Humans
Or: what if the case for typed languages in AI development is solving the wrong problem?
The emerging consensus in AI development circles: typed languages are ideal for AI agents. The type checker catches errors mechanically. If it compiles, it's probably right. Rust's strictness becomes a feature, not a burden.
There's something to this. But I think it's optimizing for the wrong thing.
The argument for types is really an argument for verification. Give the AI guardrails. Let the compiler catch mistakes. Iterate until it passes.
But verification isn't the same as understanding. And understanding is what linguistic intelligence is actually good at.
When I asked Claude directly about this, here's what it said:
tsc. I'm pattern-matching on what well-typed code looks like—linguistically. The types are documentation I read, not constraints I execute against."
Types ARE linguistic—function getUser(id: string): Promise<User> is information Claude can read and use. But Claude doesn't need them the way humans do.
Why? Because Claude doesn't forget what type a variable is halfway through a function. It doesn't lose track of what shape an object has. It can hold the whole file in context. It infers types from usage.
Humans need the compiler to catch the mistake they made because their working memory slipped. Claude doesn't have that problem.
What types actually cost
So what are types buying you in AI-native development?
What types give AI
- Documentation (useful, but good naming does this too)
- Constrained solution space (marginal benefit)
- Autocomplete hints (but AI isn't using an IDE)
What types cost
- More tokens in context
- Boilerplate (
interface,type, generics) - Build complexity
- Type gymnastics that obscure rather than clarify
And here's the key insight: the errors Claude actually makes aren't "passed string when function expected number." They're:
- Misunderstood what you wanted
- Didn't know about a domain edge case
- Made an incorrect assumption about external behavior
Types don't catch those. Dialogue catches those. You telling Claude "no, that's not quite right, here's what I meant" catches those.
The human accommodation stack
Step back and look at the entire ecosystem we've built around code: static types, linters, formatters, strict mode, eslint rules, prettier configs, pre-commit hooks.
All of it exists to compensate for human cognitive limitations:
- Humans forget — so we add type annotations to remind us
- Humans get tired — so we add linters to catch sloppy mistakes
- Humans disagree on style — so we add formatters to enforce consistency
- Humans work in teams — so we add documentation and types to communicate across people
But what if the code is generated by something that doesn't forget? That doesn't get tired? That can hold full context and regenerate cheaply?
Do you still need the same scaffolding?
Regeneration changes everything
Traditional software development assumes code is expensive to produce. You spend hours writing something, so you build defenses around that investment: types catch errors, abstractions enable modification, tests prevent regressions.
But if Claude can regenerate a function in two seconds from a description, the economics flip.
You don't need types to "protect against future changes"—change is cheap. You don't need extensive abstractions to make modification easy—you can just rewrite. The code becomes more disposable, and that's a feature.
Simple code is easier to throw away and regenerate than complex typed code with intricate generic hierarchies. Fifty lines of straightforward JavaScript beats twenty lines of clever TypeScript, because the fifty lines can be understood, explained, and regenerated without friction.
What AI-native development might actually look like
If types are a human accommodation, what does development look like when you optimize for linguistic intelligence instead?
- Simple, dynamic language — JavaScript, Python, Ruby
- Obsessively clear naming — names are documentation
- Explicit over abstract — five similar functions beats one clever generic
- Fast feedback loops — run and see, iterate quickly
- Dialogue-driven iteration — fix misunderstandings through conversation, not compilation errors
This isn't an argument against types in all cases. For large teams, for long-lived codebases, for safety-critical systems—types still make sense. They're a coordination mechanism for humans working at scale.
But for the solo builder working with AI? For the indie project deployed and forgotten? For the code that might be regenerated next week anyway?
Maybe the type checker isn't buying you what you think it is. Maybe what you actually need is a better conversation.