Introduction
I’ve been a late adopter of optional type annotations1, mostly out of laziness. Let’s be honest—type annotations sound like extra work. Writing out types, setting up configs, integrating incompletely or incorrectly typed third-party packages… it’s enough to make any solo developer stick with dynamically typed code, especially when velocity is paramount and results are all that matter.
But lately I’ve stumbled upon a realization: type annotations aren’t about doing things “the right way.” They’re about making AI do more of the work for you. Types have gone from being an unwelcome friction to an indispensable way to communicate project structure to AI agents.
direct benfits via linter, indirect benefit via machine-readable documentation that models are familiar with because of large volume of type-annotated code in training data
Code that makes its way into training data is disproportionately likely to be type-annotated: large open source projects with many collaborators usually include types for the traditional coordination benefits. Small open source projects exhibit a selection bias towards type annotation because developers are more likely to publish code that adheres to widely accepted best practices. Code with type annotations reflects better on the author, which is a key consideration since open source projects can be a major source of career capital.
LLMs don’t see the mountains of sub-par code that underpin shockingly many real-world business applications because, intellectual property considerations aside, organizations that are mired in technical debt would be too ashamed to publish their code. LLMs don’t know what to do with your sloppy code because they’re used to seeing cream-of-the-crop thousand star public repos2, not .
Well-type projects are more likely to be widely used, which means more usage examples in training data.
adding types to existing code is a way of gauging how well AI can understand it
Type annotations become more useful the more unusual your code is. If you’re using a relatively obscure framework like Svelte 5, or you’re building a custom data visualization… type annotations can help overcome the sparsity of similar code in training data.
With AI-powered coding assistants like GitHub Copilot and Cursor, type annotations have quietly become the lazy developer’s best friend. AI is simply better at understanding and generating well-typed code than loose, unstructured scripts, thanks to the massive number of strongly typed projects in its training data. That means if you use type annotations—whether in TypeScript, Python, or with DataFrames—you’ll get more accurate suggestions, fewer bugs, and even automatic fixes—without lifting a finger.
AI Works Harder When You Use Type Annotations
AI code assistants are trained on vast amounts of open-source code, and strongly typed projects make up a significant portion of that data. Since type annotations enforce structure, AI can predict and generate better code than it can with the loose, ambiguous nature of untyped programming.
Using type annotations means:
- Fewer nonsense suggestions: AI understands your data structures and generates more relevant code.
- More accurate autocompletions: Static types make it easier for AI to infer what you need next.
- Less debugging for you: AI-assisted type annotations catch errors before they break your code.
AI and Type Annotations: A Perfect Match for Lazy Devs
One of the biggest reasons developers avoid type annotations is the setup and boilerplate. But that’s exactly why AI assistants make them such a no-brainer—they take care of the annoying parts for you.
With AI, you don’t have to:
- Manually define types—AI suggests them for you.
- Waste time migrating untyped code—AI can handle most of it.
- Fix linter errors—AI tools like Cursor can identify and automatically resolve issues based on strict type rules.
Instead of fighting type annotations, you can let AI do the typing while you focus on actually building things.
Type Annotations Supercharge AI for DataFrames
When working with data-heavy applications in Python, type annotations aren’t just useful for structuring code—they also dramatically improve AI-assisted development, particularly when handling Pandas and Polars DataFrames. Libraries like Pandera provide structured schemas that serve as both validation tools and inline documentation, making AI-generated code more reliable and predictable.
The Challenges of AI with DataFrames
AI models often struggle with DataFrame operations because:
- Column names and types aren’t always obvious from the raw code.
- Implicit transformations can change DataFrame structures unpredictably.
- AI lacks awareness of expected input/output formats without explicit hints.
By using structured schemas, AI gains the necessary context to generate better code. Instead of guessing column types or making incorrect assumptions about transformations, it can rely on clear definitions from tools like Pandera.
Pandera vs. Other Documentation Approaches
Traditional documentation methods—like markdown files or inline comments—can describe DataFrame structures, but they don’t enforce correctness. Pandera, on the other hand, integrates directly into the codebase, allowing AI to:
- Generate better function signatures based on known DataFrame schemas.
- Automatically validate transformations, reducing runtime errors.
- Provide meaningful autocomplete suggestions, improving developer productivity.
AI and Polars: Schema Extraction Made Easy
Polars, a high-performance DataFrame library, makes AI-assisted development even easier by allowing type extraction directly from df.schema
. AI can use this structured output to infer proper function signatures, ensuring that generated code correctly handles DataFrame structures without unnecessary debugging.
For example, running:
print(df.schema)
Might output something like:
{'name': Utf8, 'age': Int32, 'salary': Float64}
An AI assistant can then use this information to generate properly typed function signatures:
def process_employees(df: pl.DataFrame[{'name': str, 'age': int, 'salary': float}]) -> pl.DataFrame: ...
This structured approach means AI doesn’t have to infer types from partial code—it has concrete definitions to work from, resulting in better suggestions, fewer errors, and smoother AI-assisted coding.
Type Annotations Are Future-Proof Laziness
Even if you’re just hacking together a quick script, type annotations save effort down the road. A few months later, when you revisit your project, you won’t have to decode cryptic function signatures or debug weird runtime errors—strong types will have kept everything clear and structured for you.
Plus, if your project unexpectedly grows, you won’t have to refactor a mess of dynamically typed spaghetti code. Type annotations make sure you don’t paint yourself into a corner—without you having to think too hard about it.
Conclusion
Don’t use type annotations because they’re “best practice”—use them because they make AI work better, so you can work less. AI-assisted typing means fewer bugs, better suggestions, and automatic fixes, all while letting you stay lazy.
The same principle applies to DataFrames in Python—using Pandera for Pandas or schemas in Polars gives AI the structure it needs to generate, validate, and refine code automatically. Whether you’re dealing with JavaScript, Python, or data-heavy workflows, the lazy approach is the structured approach.
If you want to write less code, debug less often, and let AI handle the heavy lifting, type annotations are the laziest smart choice you can make.
Footnotes
I would consider all of TypeScript a system for optional type annotation because at runtime it’s all JavaScript. Foregoing type annotations is always an option for frontend code. Type annotations in Python are just as toothless unless you manually opt-in and configure a static type checker like
mypy
. ↩Even if highly rated projects are a small minority of all public repos, they tend to spawn the most forks, have the most public discussion issues, and the most documentation. Projects that are more visible to you are also more visible in LLM training data, with the caveat that training data tends to lag at least six months. ↩