Elevate your JavaScript skills with TypeScript! This course will teach you how to add static typing to your code, making it more robust, scalable, and easier to maintain.
TypeScript is an open-source language developed by Microsoft. It's a superset of JavaScript, meaning any valid JavaScript code is also valid TypeScript code. The key difference is that TypeScript adds **static typing** to JavaScript. This allows you to define the types of variables, function parameters, and return values, catching errors during development rather than at runtime. TypeScript code is then "transpiled" into plain JavaScript so that browsers and Node.js can understand it.
TypeScript = JavaScript + Static Types + Tooling!
To run TypeScript code, you first need to compile it into JavaScript. Visual Studio Code is the recommended editor due to its excellent TypeScript support.
TypeScript compilation and package management rely on Node.js and its package manager (npm or Yarn).
node -v
npm -v
Install the TypeScript compiler (`tsc`) globally using npm.
npm install -g typescript
tsc -v
tsc --init
// app.ts
function greet(name: string): string {
return `Hello, ${name}!`;
}
const userName: string = "TypeScript User";
console.log(greet(userName));
// This would cause a TypeScript error (but compile to JS if you force it)
// console.log(greet(123));
tsc app.ts
This command will create an `app.js` file in the same directory.
node app.js
VS Code's integrated terminal and built-in TypeScript support (like autocompletion and error checking) make it an ideal environment for TypeScript development!
TypeScript introduces several basic types to explicitly define the kind of data a variable can hold.
Represents textual data.
let greeting: string = "Hello, TypeScript!";
console.log(greeting);
Output:
Hello, TypeScript!
Represents both integer and floating-point numbers.
let age: number = 30;
let price: number = 99.99;
console.log(age, price);
Output:
30 99.99
Represents `true` or `false`.
let isActive: boolean = true;
console.log(isActive);
Output:
true
Defines an array where all elements are of a specific type.
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];
console.log(numbers, names);
Output:
[ 1, 2, 3 ] [ 'Alice', 'Bob' ]
An array with a fixed number of elements whose types are known, but need not be the same.
let user: [number, string] = [1, "Max"];
console.log(user[0], user[1]);
Output:
1 Max
A way of giving more friendly names to sets of numeric values.
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
console.log(c); // Output: 1 (by default, enums start at 0)
Output:
1
A powerful way to work with existing JavaScript, allowing you to opt-out of type checking. Use with caution.
let unknownValue: any = 4;
unknownValue = "maybe a string";
unknownValue = false;
console.log(unknownValue);
Output:
false
Used for functions that do not return any value.
function warnUser(): void {
console.log("This is a warning message.");
}
warnUser();
Output:
This is a warning message.
Represent the absence of a value. By default, `null` and `undefined` are subtypes of all other types.
let u: undefined = undefined;
let n: null = null;
console.log(u, n);
Output:
undefined null
Interfaces define the "shape" that an object must have. They are a powerful way to enforce consistency and improve code readability and maintainability.
interface User {
id: number;
name: string;
email?: string; // Optional property
}
function printUser(user: User) {
console.log(`ID: ${user.id}, Name: ${user.name}`);
if (user.email) {
console.log(`Email: ${user.email}`);
}
}
let user1: User = { id: 1, name: "Alice" };
let user2: User = { id: 2, name: "Bob", email: "bob@example.com" };
printUser(user1);
printUser(user2);
Output:
ID: 1, Name: Alice ID: 2, Name: Bob Email: bob@example.com
TypeScript supports object-oriented programming with classes, which act as blueprints for creating objects (instances).
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
console.log(greeter.greet());
Output:
Hello, world
Generics allow you to write reusable code that works with a variety of types, rather than a single one. They provide a way to create components that can work over a variety of types rather than a single type.
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString");
let output2 = identity<number>(100);
console.log(output1);
console.log(output2);
Output:
myString 100
Type aliases create a new name for a type. Type aliases are sometimes similar to interfaces, but they can also name primitives, union types, tuples, and any other types that you can define.
type StringOrNumber = string | number;
function printId(id: StringOrNumber) {
console.log(`Your ID is: ${id}`);
}
printId("abc");
printId(123);
Output:
Your ID is: abc Your ID is: 123
Union types allow a variable to hold values of several types. They are useful when a value could be one of several types.
function printStatusCode(code: string | number) {
console.log(`My status code is ${code}.`);
}
printStatusCode(404);
printStatusCode("200");
Output:
My status code is 404. My status code is 200.
TypeScript can often infer the type of a variable based on its initial value, even if you don't explicitly declare it. This helps keep your code concise.
let inferredString = "Hello"; // TypeScript infers type as string
// inferredString = 123; // Error: Type 'number' is not assignable to type 'string'.
let inferredNumber = 500; // TypeScript infers type as number
// inferredNumber = "five hundred"; // Error: Type 'string' is not assignable to type 'number'.
console.log(inferredString, inferredNumber);
Output:
Hello 500
You've completed the TypeScript Fundamentals Course! You now understand the core concepts of TypeScript and how to set up your environment for development.
Continue practicing by converting existing JavaScript projects to TypeScript, and explore more advanced topics like advanced types, decorators, and integrating TypeScript with popular frameworks!