TypeScript là một dự án mã nguồn mở được phát triển bởi Microsoft, nó có thể được coi là một phiên bản nâng cao của Javascript bởi việc bổ sung tùy chọn kiểu tĩnh và lớp hướng đối tượng.
TypeScript giúp phát hiện lỗi sớm nhờ kiểu tĩnh, cải thiện gợi ý code, dễ bảo trì, hỗ trợ OOP, Generics, Interface, và Decorators. Nó tương thích JavaScript, dễ debug, hỗ trợ module, phù hợp cho dự án lớn
1. Basic Type
Các kiểu dữ liệu được quy định chặt chẽ. Khi đặt cho biến 1 kiểu dữ liệu, nếu gán cho biến 1 giá trị không đúng kiểu dữ liệu đó lập tức sẽ báo lỗi. Điều này có thể giúp phát hiện lỗi trong quá trình phát triển và cải thiện khả năng đọc mã.
//string
let fullname : string;
fullname = 'Van Phuc';
//fullname = 10; báo lỗi vì gán không đúng kiểu dữ liệu
//number, boolean, undefined, null tương tự
let age: number;
age = 30
age = "string".length
//any: có thể gán được nhiều kiểu dữ liệu
let anyType: any;
anyType = 10;
anyType = 'VP';
anyType = true;
2. Object
Trong TypeScript, object type được dùng để đại diện cho các giá trị không phải primitive (string, number, boolean, null, undefined, symbol, bigint)
let person: {name: string; age: number};
person = {name: "Men", age: 20};
//Có thể sử dụng ? sau tên biến để không bắt buộc phải gán giá trị cho biến
let person1: {name: string; age?: number};
person1 = {name: "Men"};
3. Array
Mảng (Array) là một tập hợp các phần tử có cùng kiểu dữ liệu. TypeScript cung cấp nhiều cách để định nghĩa kiểu dữ liệu cho mảng.
//any
let arr : any[] = []
arr.push(3);
arr.push("string");
arr.push(true);
//string array
let arr2 = ["a", "b", "c"];
let arr3 : string[] = [];
let arr4 : Array<string> = ["a", "b", "c"]
arr2.push(20) // Lỗi
//number, boolean array tương tự
//object array
let blogs : {title: string, body: string}[] = [{title: "hi", body: "abc"}];
blogs.push({title: "hello", body: "abc"})
4. Function
Định nghĩa kiểu dữ liệu cho hàm, bao gồm tham số và kiểu trả về.
- Function return value
function sum(a, b){
return a+b
}
sum("hi", 2)
function sum1(a: number, b: number): number {
return a + b;
}
sum1(5, 10)
//type: định nghĩa kiểu dữ liệu, có thể tái sử dụng
type functionType = (num1: number, num2: number) => number;
const sum2:functionType = (a, b) => {
return a + b
}
- Function not return value
function logMessage(message: string): void {
console.log(message);
}
logMessage("Hello");
5. Union
Union (|) trong TypeScript cho phép một biến hoặc tham số có thể nhận nhiều kiểu dữ liệu khác nhau.
Kết hợp với type để tạo kiểu dữ liệu linh hoạt hơn.
Union giúp code linh hoạt hơn nhưng cần kiểm tra cẩn thận khi sử dụng.
let size: string | number;
size = "XL"
size = 30
const addNumberOrString = (a: number | string, b: number | string) => {
if(typeof a === "number" && typeof b === "number") {
return a + b
}
if(typeof a === "string" && typeof b === "string") {
return a.concat(b)
}
throw new Error("Arguments must be both numbers or both strings.");
}
6. Enum
Enum là một kiểu dữ liệu đặc biệt giúp định nghĩa một tập hợp các giá trị đặt tên. Nó giúp code dễ đọc, dễ bảo trì hơn khi làm việc với các giá trị cố định.
enum Colors {
RED = "RED",
BLUE = "BLUE",
GREEN = "GREEN"
}
let color = Colors.RED //output : RED
Nếu không gán giá trị, TypeScript sẽ tự động gán số từ 0, 1, 2...
Với các enum được gắn giá trị số có thể gọi ngược lại
enum Colors {
RED = 10,
BLUE, // 11 (tự động tăng)
}
console.log(Colors.RED); // Output: 10
console.log(Colors[11]); // Output: BLUE
7. Interface và Type
Interface định nghĩa cấu trúc đối tượng với các thuộc tính và phương thức, type cũng tương tự nhưng linh hoạt hơn.
// Dùng interface
interface PersonInterface {
name: string;
age: number;
}
// Dùng type
type PersonType = {
name: string;
age: number;
};
const person1: PersonInterface = { name: "A", age: 20 };
const person2: PersonType = { name: "B", age: 22 };
Khi nào dùng interface và type?
- Dùng interface nếu cần kế thừa (extends) và dùng với class.
- Dùng type nếu cần Union (|), Intersection (&), dùng Tuple, function. (Tuple là một kiểu dữ liệu đặc biệt, cho phép khai báo một mảng có số lượng phần tử cố định và kiểu dữ liệu xác định cho từng phần tử.)
- Nếu chỉ định nghĩa Object, cả hai đều dùng được.
8. Generic
Generic trong TypeScript cho phép tạo ra các thành phần tái sử dụng mà có thể hoạt động với nhiều loại dữ liệu khác nhau.
Sử dụng Generic trong TypeScript mang lại nhiều lợi ích so với any hoặc các kiểu kết hợp (union types), đặc biệt khi bạn cần tạo ra mã nguồn an toàn và có thể tái sử dụng.
function getFirstElement<ElementType>(arr: ElementType[]) {
return arr[0];
}
const arr1 = [1, 2, 3];
console.log(getFirstElement(arr1));
const arr2 = ["a", "b", "c"];
console.log(getFirstElement(arr2));
Khi nào nên sử dụng Generic:
- Không biết trước kiểu dữ liệu cụ thể.
- Khi làm việc với dữ liệu khác nhau nhưng cấu trúc giống nhau.
- Khi cần tái sử dụng mã nguồn.
- Khi cần tính an toàn về kiểu dữ liệu.
- Khi làm việc với các kiểu dữ liệu phức tạp.
- Khi cần linh hoạt mở rộng mã nguồn.
9. Class
TypeScript hỗ trợ lập trình hướng đối tượng (OOP) thông qua Class, giúp quản lý dữ liệu và hành vi một cách có tổ chức.
Class trong TypeScript mạnh mẽ hơn với kiểu dữ liệu, phạm vi truy cập, kế thừa, interface, generic,...
class Person {
name: string //Có thể truy cập bất cứ đâu
protected age: number //Có thể truy cập trong class và class con
private weight: number; //Chỉ truy cập trong class
constructor(name: string, age: number, weight: number){
this.name = name
this.age = age
this.weight = weight
}
getPersonInfo(): void {
console.log(`Name: ${this.name}, Age: ${this.age}`);
}
private getWeight(): number {
return this.weight; // Chỉ có thể dùng trong class
}
}
const pers = new Person("Men", 20, 60);
pers.getPersonInfo(); // Được phép gọi
pers.weight; //Lỗi vì `weight` là `private`
pers.age; //Lỗi vì `age` là `protected`
KẾT LUẬN
Trên đây là những kiến thức cơ bản mà tôi tìm hiểu được về Typescript mặc dù còn nhiều tính năng và khái niệm khác. Tôi sẽ tiếp tục tìm hiểu và cập nhật trên bài viết này trong thời gian tới...
Top comments (0)