TL;TR
Since in TypeScript all types are nullable, there are some traps the developer can fall into like unterminated functions.
The domain
As it turned out from my previous post, in TypeScript every type is nullable: this means that for every type null and undefined are valid values.
Not to mention the notorious any, which fits any type well.
The problem
Going a bit further we can easily realise that given a function (string) => number
like
function countCharacters(name: string): number {
if (name) {
return name.length;
}
}
the compiler will not complain about it even if actually my function is returning (number | undefined)
.
And a block which is using that function like, for instance
const names: Array<string> = ["Doc", "Grumpy", "Sleepy", null, undefined]; // yes, it’s fine for TS
let i: number;
let total = 0;
for (i = 0; i < names.length; i += 1) {
total += countCharacters(names[i]);
}
console.log(total);
will end up with NaN as a result: the names
array is accepted with both null and undefined, and since the function countCharacters
is implicitly allowed to return undefined our code is applying the operator + to different types which results in NaN.
The bottom line
Nonetheless seems impossible to check against such errors as of 1.8, because for TypeScript this is not a problem but rather a feature: thanks to type nullability it is compiling even against legacy codebases and moreover allows the average developer to write code before thinking.
There are some proposals to fix it like a compiler’s options or an identifier but as of today we can only use run time assertions, a strict linter and force our fellows to read Douglas Crockford.
One good alternative is to switch over Flow.