Code on cover pic: MUI
Seems like TypeScript won among other statically typed languages for web. Does it mean it’s flawless? No; instead some of its features are at least unexpected. Let’s look at them closely.
1. TypeScript doesn’t provide 100% type safety
This code is not typesafe:
const a: number[] = []
const x: number = a[0]
console.log(x) // undefined!
Literally number[]
type means: for any index there’s an item of type number
. Which is not possible, of course! The following type would be correct for array: (number|undefined)[]
, but no-one actually writes like this because it reads very verbose. Instead, developers try just keeping in mind that any array indexing may produce undefined
, and only tuples are really typesafe.
2. TypeScript is not the different web language
TypeScript acts in a space beyond and invisible to web. When you write TS code, you actually create 2 programs:
- One runs in a browser, and it’s JavaScript program
- Another runs only within TS compiler, and it’s completely gone once your bundle is ready
This means two things:
- To write a good TS code you need to know JS on the first place
- Writing on TS doesn’t mean you are expected to write like on some “traditional” backend language like Java or C#—with classes and OOP. Idiomatic TS looks just like JS—with objects and functions.
3. TypeScript typing is a duck typing
These two types are 100% compatible in TS:
type Point = {
x: number,
y: number
}
type Coords = {
x: number,
y: number
}
You may assign a var of a first type to a var of another, and that’s totally fine:
const p: Point = {x: 1, y: 2}
const c: Coords = p
It works the same way with interfaces and classes.
This is referred to as “structural typing”. Its antonym is “nominal typing” which would interpret Point
and Coords
as completely different and incompatible types.
That was especially surprising for me (I’m from Java world), and I was trying first to mimic nominal typing with brands; however shortly I discovered it’s easier to change a bit my mental model, and start thinking in structural types. Indeed, just like vars are aliases to values, types are aliases to objects’ shapes.
4. TypeScript has exceptionally rich type system, but you are not supposed to use its full power
TypeScript type system is Turing complete which means it can implement any logic, for example, computing Fibonacci sequence. Does that mean your types need to be that complex? I don’t think so.
My impression is that TypeScript’s complexity is caused by JS libs created years before TS got popular — Lodash, Ramda, Redux, and many many more. These libs were designed without keeping static types in mind, that’s why their typings, created afterwards, are very challenging to understand. Good code is a code easy to read — that’s why you’d better keep your types simple.
5. There’s no TypeScript standard
Unlike C, Java, JavaScript, or Python there’s no formal document which describes how TypeScript must work. This means it’s nearly impossible to make an alternative yet compatible TypeScript implementation, and we are bound to the official Microsoft implementation for years.
What does all these mean? Well… not that much. Any technology has its limitations, and there’s not a single perfect thing in the world. TypeScript is special because it got very popular even with all these drawbacks—which are quite serious IMO. But whether we like it or not, we are bound to TypeScript, and understanding its weaknesses is crucial for writing a good code.
Top comments (0)