-
TypeScript is a superset of JavaScript. But it doesnot add more feature in JavaScript. It just allow us to write JavaScript as a precise manner so that code get less error at runtime.
-
TypeScript is all about type safety
-
TypeScript only job is
Static Checking
which means it checks type on runtime and shows error while we are writing code -
TypeScript transpile code into JavaScript
-
It is a development tool which help us to write better code
npm install -g typescript
npm install typescript --save-dev
let variableName: type = value
let greetings: string = 'Hello'
console.log(greetings)
Error: Cannot redeclare block-scoped variable 'greetings'.ts(2451)
Temporary Solution: export {}
- string represents string values like "Hello, world"
- number is for numbers like 42. JavaScript does not have a special runtime value for integers, so there’s no equivalent to int or float - everything is simply number
- boolean is for the two values true and false
Note: 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.
let name: string = 'Nur Rafi'
let age: number = 20
let isMuslim: boolean = true
We don't have to declare types on every place, TypeScript is so smart that he can detect when we assign values. In order to write better code allways declare type with colon is not best practice. We should declare types when we required.
To specify the type of an array like [1, 2, 3]
, you can use the syntax number[]
; this syntax works for any type (e.g. string[]
is an array of strings, and so on). You may also see this written as Array<number>
, which means the same thing. We’ll learn more about the syntax T<U>
when we cover generics
.
Note: [number]
is a different thing; refer to the section on Tuples
.
let arrayOfNumber: number[] = [1, 2, 3]
let arrayOfString: string[] = ['a', 'b', 'c']
_WRONG_
let superHero = []
_or_
let superHero: [] = []
superHero.push('spiderman')
// Error: Argument of type 'string' is not assignable to parameter of type 'never'
_CORRECT_
let superHero: string[] = []
_or_
let superHero: Array<string> = []
superHero.push('spiderman')
interface User = {
name: string,
isActive: boolean
}
let allUsers: User[] = []
allUsers.push({name: 'Nur', isActive: true})
let data1: number[] = [1, 2, 3]
let data2: string[] = ['1', '2', '3']
_WRONG_
let data3: number[] | string[] = ['1', '2', 3] // Error: Either all items are number neither all are string
_CORRECT_
let data3: (number | string)[] = ['1', '2', 3]
A tuple type is another sort of Array type that knows exactly how many elements it contains, and exactly which types it contains at specific positions. It is usefull we do something based on items order.
Typescript array push method can't catch a tuple type of the array
let rgb: [number, number, number] = [255, 255, 255]
let user: [string, number, boolean]
user = ['', 99, true]
user.push('anything') // Here we can use array methods which breaks restriction
SOLUTION: We can declare our tuple to be readonly
or as const
to prevent the push function from working on the tuple at all
const testArray:readonly [number, string] = [10, 'test'] as const;
testArray.push('test') // Error: Property 'push' does not exist on type 'readonly [number, string]'
An Enum (or Enumeration) is a data type that includes a set of named values called elements or members.
Note: If we don't use const
it will generate IIEF which contains more code than what we wrote
const enum SeatChoice {
AISLE = 'aisle',
MIDDLE = 'middle',
WINDOW = 'window'
}
const Seat = SeatChoice.AISLE
TypeScript also has a special type, any
, that you can use whenever you don’t want a particular value to cause typechecking errors. This is not a best practice.
The any
type is useful when you don’t want to write out a long type just to convince TypeScript that a particular line of code is okay.
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;
function loginUser(name: string, email: string, isPaid: boolean = false){
return console.log(name, email, isPaid)
}
const heros = ["thor", "spiderman", "ironman"]
// Good
heros.map((hero: string) => {
return `Hero is ${hero}`
})
// Better
heros.map((hero): string => {
return `Hero is ${hero}`
})
Typescript automatically detect type so we dont have to declare parameter type in this case but we must declare return type
// No type annotations here, but TypeScript can spot the bug
const names = ["Alice", "Bob", "Eve"];
names.forEach(function (s) {
console.log(s.toUppercase());
// Error: Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?
});
void
represents the return value of functions which don’t return a value.
function consoleError(errMsg: string): void{
console.log(errMsg)
}
_OR_
function consoleError (errmsg: string){
return
}
Note: In JavaScript, a function that doesn’t return any value will implicitly return the value undefined. However, void
and undefined
are not the same thing in TypeScript.
The never type represents values which are never observed. In a return type, this means that the function throws an exception or terminates execution of the program.
function handleError (errmsg: string): never{
throw new Error (errmsg)
}
function printCoord(pt: { x: number; y: number }) {
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 });
Object types can also specify that some or all of their properties are optional. To do this, add a ?
after the property name
function printName(obj: { first: string; last?: string }) {
// do something
}
function createFunction():{}{}
function createCourse():{name: string, price: number}{
return { name: 'TypeScript', price: 10000}
}
A union type is a type formed from two or more other types, representing values that may be any one of those types.
function printId(id: string | number): string | number {
if (typeof id === "string") {
return console.log(id.toUpperCase());
} else {
return console.log(id);
}
}
// OK
printId(101);
// OK
printId("id-202");
// Error
printId({ myID: 22342 });
function welcomePeople(x: string[] | string) {
if (Array.isArray(x)) {
// Here: 'x' is 'string[]'
console.log("Hello, " + x.join(" and "));
} else {
// Here: 'x' is 'string'
console.log("Welcome lone traveler " + x);
}
}
For primative data type we cannot modify readonly
property, But for non-primative data type like array we can modify array with array methods.
interface User {
readonly _id: string,
name: string,
email: string,
isActive: boolean
}
let myUser: User = {
_id: '12345',
name: 'Nur',
email: '[email protected]',
isActive: true
}
myUser.email = '[email protected]'
myUser._id = '999'
// Error: Cannot assign to '_id' because it is a read-only property
type Point = {
x: number;
y: number;
};
// Exactly the same as the earlier example
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
An interface declaration is another way to name an object type
interface Point {
x: number;
y: number;
}
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
x: number = y
x = y as number
Type annotations are used to tell the compiler that a variable through its lifetime can only have a specified type. When someone will try to assign a type that is incompatible, an error will be thrown.
let age: number = 18;
let name: string = "John";
age = name;
// Error: Argument of type 'string' is not assignable to parameter of type 'number'.
Type assertions are used to cast variables to a specific type. When you use it you tell the compiler that you know better what type the variable has and he does not need to guess it. For example:
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
_OR_
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
function printText(s: string, alignment: "left" | "right" | "center") {
// do something
}
printText("Hello world", "left");
printText("Hello world", "centre"); // spelling mistake
// Error Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.
const PI: 3.14 = 3.14
Loose form of class
interface User {
readonly: _id,
email: string,
name: string,
googleId?: string,
startTrial: () => void,
startTrialAgain(): string
getCoupone(code: string): number
}
// Re-opening interface
interface User {
githubToken: string
}
// Extends
interface Admin extends User {
role: string
}
tsc --init // create tsconfig.json