Syntax
Hello World
console.log("Hello world!");
Rules
Naming Conventions
Comments
//Single line comment
/* Multi
line
comment */
Variables
Declaration
let x;
// with type
let x: number; //types are specified using type annotations
Initialization
x = true // type-automatically inferred as boolean
x = 123; //compile-time error
Both at once
let x = true // type-automatically inferred as boolean
x = 123; //compile-time error
Constants
const PI = 3.14;
const PI = 3.14;
Data types
Primitives
string
number
: No int or float. Every number is simplynumber
.boolean
💡The type names String, Number, and Boolean (starting with capital letters) are legal, but refer to some special built-in types that will very rarely appear in your code. Always use string, number, or boolean for types.
-
any
: Special type which you can use whenever you don't want a particular value to cause typechecking errors.let obj: any = { x: 0 }; // None of the following lines of code will throw compiler errors. // Using `any` disables all further type checking, and it is assumed // you know the environment better than TypeScript. obj.foo(); obj(); obj.bar = 100; obj = "hello"; const n: number = obj;
Can be disabled by setting
noImplicitAny
flag in lang.ts.config (Private)
Compound
Array
Declaration
let x: number[]
Array<number> arr;
Initialization
x = [1,2,3] // type inferred as Array
Both at once
let x = [1,2,3] // type inferred as Array
Strings
let gina: string;
gina = "boyle";
let holt = "kevin"; // type inferred as string
Objects (kind of like structures)
// The parameter's type annotation is an object type
function printCoord(pt: { x: number; y: number }) { // here the type of pt is defined as composed of x and y
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 3, y: 7 });
Optional properties
function printName(obj: { first: string; last?: string }) {
// ...
}
// Both OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });
Checking for undefined
mandatory for optional properties
function printName(obj: { first: string; last?: string }) {
// Error - might crash if 'obj.last' wasn't provided!
console.log(obj.last.toUpperCase()); //'obj.last' is possibly 'undefined'.
if (obj.last !== undefined) {
console.log(obj.last.toUpperCase());
}
//modern JavaScript syntax:
console.log(obj.last?.toUpperCase());
}
Union Types
Combination of multiple types. Union type basically says that a variable/parameter can be either of the types within the union.
function printId(id: number | string) {
console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// Error
printId({ myID: 22342 });
Any operation on such parameter/variable will only work if the operation is valid for both all types in the union.
function printId(id: number | string) {
console.log(id.toUpperCase()); //Error - method not applicable for number
//Solution to this - narrow down the type
if (typeof id === "string") {
// In this branch, id is of type 'string'
console.log(id.toUpperCase());
} else {
// Here, id is of type 'number'
console.log(id);
}
}
💡It might be confusing that a union of types appears to have the intersection of those types’ properties. This is not an accident - the name union comes from type theory. The union number | string is composed by taking the union of the values from each type. Notice that given two sets with corresponding facts about each set, only the intersection of those facts applies to the union of the sets themselves. For example, if we had a room of tall people wearing hats, and another room of Spanish speakers wearing hats, after combining those rooms, the only thing we know about every person is that they must be wearing a hat.
Type Aliases
// For object types
type Point = {
x: number;
y: number;
};
//For union types
type ID = number | string;
// For primitive - Unnecessary but legal
type UserInputString = string;
Interfaces
interface Point {
x: number;
y: number;
}
Classes
Creating objects
Using objects
Operators
Flow
Conditionals
Loops
Traditional
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
for...of
Loops on elements.
for (let index of fruits) {
console.log(fruits[index]);
}
for...in
Loops on indexes/keys.
for (let index in fruits) {
console.log(fruits[index]);
}
💡 You'd think that index
will be a number
, but no, index here is a string
. What's more? You can access elements using this index (as showm above), because its converted by Implicit Casting. But if you use it to initialize another variable, like j=i+1
, you can't use j
as a number
, j
will also be a string
. Weird stuff.
So prefer for..of or traditional for loop for arrays. Use for..in for things like Maps.
Functions/Methods
Parameter type annotation
function greet(name: string) {
console.log("Hello" name.toUpperCase() + "!!");
}
Return type annotation
function getFavoriteNumber(): number {
return 26;
}
Functions which return Promises
async function getFavoriteNumber(): Promise<number> {
return 26;
}
Anonymous functions
const names = ["Alice", "Bob", "Eve"];
//using function keyword
names.forEach(function (s) {
console.log(s.toUpperCase());
});
// Arrow functions
names.forEach((s) => {
console.log(s.toUpperCase());
});