Understanding TypeScript
A teammate recently ran into an issue and assumed it was caused by the TypeScript compiler. They even sent me this link: flatMap is not a function #1822.
The fix was straightforward—the error clearly comes from calling array methods on a non-array—but the teammate still blamed TypeScript. That exposes a fundamental misunderstanding. To avoid repeating the same explanations, I’m summarizing the basics here.
Positioning TypeScript
Typed JavaScript at Any Scale.
That’s the official tagline. TypeScript is simply JavaScript with types—Type + Script
. The language itself doesn’t take responsibility for JavaScript runtime compatibility.
TypeScript’s Core Weapon: Types
JavaScript is flexible, but that freedom has a cost: higher risk and lower maintainability. TypeScript brings Java-like structure so every object and function has a clear type. It’s more flexible than Java though—union types, utility types, and so on.
Notice that TypeScript includes both any
and unknown
, representing the upper and lower bounds of types. But remember: if your entire project relies on any
, unknown
, and @ts-ignore
, you might as well skip TypeScript. Unlimited and unknown types give you no safety net.
Using TypeScript in Real Projects
In practice, TypeScript is your development language. Lean on types so you catch bugs during development—not after the compiler strips types, the bundler runs, and production crashes.
Recommended Tooling
- Babel – transpile TypeScript during development or bundling.
- Tools like awesome-typescript-loader are outdated. Babel is more powerful, and its plugin ecosystem helps with JavaScript compatibility.
- ESLint – enforce code quality for both TS and JS.
- TSLint is deprecated; ESLint now covers everything.
Choosing a TypeScript Version
- In general, the newest version is best. TypeScript is just a typed superset of JavaScript, so upgrading won’t break runtime behavior. In fact, newer versions improve type safety.
- TypeScript ultimately compiles to JavaScript, which runs in browsers or Node. Compatibility issues come from the compilation settings and target runtime.
- In real projects, dependencies often ship TypeScript code or definitions, which can make upgrades harder. To manage this:
- Keep your version close to the versions used by your dependencies—minor version differences are usually fine.
- Some teams disable type checking during bundling. I don’t recommend it, but it’s technically possible since types don’t affect runtime behavior.
Final Thoughts
In short, TypeScript only adds types. If you adopt it, make the most of those types and be explicit wherever you can.