You can skip this chapter if you are already sure that you will learn and use TypeScript.
If you are still unsure – this chapter is my sales pitch.
While you are editing TypeScript code in an integrated development environment, you get warnings if you mistype names, call functions incorrectly, etc.
Consider the following two lines of code:
function func() {}
funcc();
For the second line, we get this warning:
Cannot find name 'funcc'. Did you mean 'func'?
Another example:
= 0;
const a = true;
const b = a + b; const result
This time, the error message for the last line is:
Operator '+' cannot be applied to types 'number' and 'boolean'.
Documenting parameters of functions and methods is something that many people do, anyway:
/**
* @param {number} num - The number to convert to string
* @returns {string} `num`, converted to string
*/
function toString(num) {
return String(num);
}
Specifying the types via {number}
and {string}
is not required, but the descriptions in English mention them, too.
If we use TypeScript’s notation to document types, we get the added benefit of this information being checked for consistency:
function toString(num: number): string {
String(num);
return }
Whenever I migrate JavaScript code to TypeScript, I’m noticing an interesting phenomenon: In order to find the appropriate types for parameters for a function or method, I have to check where it is invoked. That means that static types give me information locally that I otherwise have to look up elsewhere.
And I do indeed find it easier to understand TypeScript code bases than JavaScript code bases: TypeScript provides an additional layer of documentation.
This additional documentation also helps when working in teams because it is clearer how code is to be used and TypeScript often warns us if we are doing something wrong.
If there are type definitions for JavaScript code, then editors can use them to improve auto-completion.
An alternative to using TypeScript’s syntax, is to provide all type information via JSDoc comments – like we did at the beginning of this chapter. In that case, TypeScript can also check code for consistency and generate type definitions. For more information, see chapter “Type Checking JavaScript Files” in the TypeScript handbook.
Refactorings are automated code transformations that many integrated development environments offer.
Renaming methods is an example of a refactoring. Doing so in plain JavaScript can be tricky because the same name might refer to different methods. TypeScript has more information on how methods and types are connected, which makes renaming methods safer there.
TypeScript tends to quickly support ECMAScript stage 4 features (such features are scheduled to be included in the next ECMAScript version). When we compile to JavaScript, the compiler option --target
lets us specify the ECMAScript version that the output is compatible with. Then any incompatible feature (that was introduced later) will be compiled to equivalent, compatible code.
Note that this kind of support for older ECMAScript versions does not require TypeScript or static typing: The JavaScript compiler Babel does it too, but it compiles JavaScript to JavaScript.
TypeScript code can be very heavyweight. But it doesn’t have to be. For example, due to type inference, we can often get away with few type annotations:
function selectionSort(arr: number[]) { // (A)
for (let i=0; i<arr.length; i++) {
= findMinIndex(arr, i);
const minIndex , arr[minIndex]] = [arr[minIndex], arr[i]]; // swap
[arr[i]
}
}
function findMinIndex(arr: number[], startIndex: number) { // (B)
= arr[startIndex];
let minValue = startIndex;
let minIndex for (let i=startIndex+1; i < arr.length; i++) {
= arr[i];
const curValue if (curValue < minValue) {
= curValue;
minValue = i;
minIndex
}
};
return minIndex
}
= [4, 2, 6, 3, 1, 5];
const arr selectionSort(arr);
.deepEqual(
assert, [1, 2, 3, 4, 5, 6]); arr
The only locations where this TypeScript code is different from JavaScript code, are line A and line B.
There are a variety of styles in which TypeScript is written:
Initially, TypeScript did invent a few language constructs of its own (e.g. enums). But since ECMAScript 6, it mostly stuck with being a strict superset of JavaScript.
My impression is that the TypeScript team likes JavaScript and doesn’t want to replace it with something “better” (which is the goal of, e.g., Dart). They do want to make it possible to statically type as much JavaScript code as possible. Many new TypeScript features are driven by that desire.