JavaScript is a dynamically typed programming language, which means a variable's type can change while the code is executing.
var dinner = 'tacos';
console.log(dinner); // 'tacos'
dinner = 12;
console.log(dinner); // 12
The variable dinner
starts out as the string 'tacos'
and then becomes the number 12
. We can verify that the types are changing by using JavaScript's typeof
operator.
var dinner = 'tacos';
console.log(typeof dinner); // string
dinner = 12;
console.log(typeof dinner); // number
To those familar with JavaScript, the ability to change a variable's type might seem normal, but it's not something you see in statically typed langauges, such as Java.
String dinner = "tacos";
System.out.println(dinner); // "dinner"
String dinner = 42; // error: incompatible types: int cannot be converted to String
While dynamically typed variables are part of what makes JavaScript unique, they can also cause unexpected behavior.
function add(x, y) {
return x + y;
}
add(1, 2); // returns 3
add('1', 2); // returns '12'
If you're not careful with your types, these kinds of bugs can pop up. But we're always careful, so we're probably good?
This, as well as many other gotchas in the JavaScript language, is why Microsoft created TypeScript.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript
In other words, it's everything the JavaScript language is, as well as extra features and functionality that aren't currently a part of JavaScript itself.
When you write TypeScript, which is just JavaScript with some extra features built in, it's then compiled into plain JavaScript by the TypeScript compiler, which you can then run in a browser (or node). It's during compilation that TypeScript is able to surface potential errors with your application.
As you might have guessed, one of the extra features that TypeScript provides is type checking. Let's see how using this can help us by looking back at our previous example.
var dinner = 'tacos';
console.log(dinner);
dinner = 12;
console.log(dinner);
Without any changes, when TypeScript compiles this code to JavaScript, it's already surfacing problems.
Type '12' is not assignable to type 'string'
TypeScript is able to infer that the dinner
variable is a string, and helps us detect errors when a specific type may be expected.
While it's nice that TypeScript can infer a variable's type, we can use TypeScript to explicitly enforce a type by using TypeScript's Type Annotation.
var dinner: string = 'tacos';
console.log(dinner);
dinner = 12;
console.log(dinner);
This added functionality : string
tells the TypeScript compiler, as well as other developers looking at your code, that the dinner
variable is a string and should always stay as such.
While TypeScript is great at infering types, sometimes it can't quite figure it out.
function add(x, y) {
return x + y;
}
add(1, 2); // returns 3
add('1', 2); // returns '12'
Initially the TypeScript compiler gives us this message:
Parameter 'x' implicitly has an 'any' type.
Parameter 'y' implicitly has an 'any' type.
When TypeScript isn't able to infer a type, it implicitly assigns the type of any
. In this case, the any
type means TypeScript couldn't infer the type. Luckily, as the authors of this code we know that our add()
function should accept numbers. Let's annotate our function accordingly.
function add(x: number, y: number) {
return x + y;
}
add(1, 2); // returns 3
add('1', 2); // returns '12'
Now TypeScript is able to help surface a more meaningful error that will catch this bug earlier.
Argument of type '"1"' is not assigneable to parameter of type 'number'
NOTE: The any
type can also be used whenever you don't want a particular value to cause typechecking errors (i.e. var dinner: any = 'tacos';
).
JavaScript's dynamically typed variables can sometimes cause unintended behavior when our code is executing. TypeScript aims to catch potential bugs by introducing new features to the JavaScript language that can help catch errors earlier, when compiling your TypeScript code into plain JavaScript.
Type checking and annotations are two of the many features TypeScript provides, and they can help surface potential bugs earlier, helping you build a more robust application.