TypeScript là gì? TypeScript là ngôn ngữ lập trình mã nguồn mở do Microsoft phát triển, mở rộng JavaScript bằng hệ thống kiểu tĩnh. Code TypeScript được biên dịch thành JavaScript thuần, nên chạy được ở mọi nơi JavaScript chạy: trình duyệt, Node.js, Deno, Bun. Lợi ích lớn nhất là phát hiện lỗi ngay khi viết code thay vì khi người dùng gặp lỗi. Bài viết giải thích sự khác nhau giữa TypeScript và JavaScript, các kiểu dữ liệu cơ bản, interface, generic và cách dùng TypeScript với React.
Vì sao lập trình viên JavaScript nên học TypeScript?
JavaScript là ngôn ngữ kiểu động: một biến có thể là số lúc này và chuỗi lúc khác. Điều đó linh hoạt nhưng dễ gây lỗi khó phát hiện khi dự án lớn dần. Ví dụ:
function tinhTong(gia, soLuong) {
return gia * soLuong;
}
tinhTong("29000", 2); // 58000 – JavaScript tự ép kiểu
tinhTong(undefined, 2); // NaN – lỗi âm thầm
Với TypeScript:
function tinhTong(gia: number, soLuong: number): number {
return gia * soLuong;
}
tinhTong("29000", 2); // Lỗi ngay trong editor: string không gán được cho number
Những lợi ích chính:
- Bắt lỗi sớm: sai kiểu, gọi thuộc tính không tồn tại, quên xử lý
nullđược phát hiện khi viết code. - Gợi ý code tốt hơn: editor biết chính xác object có những thuộc tính gì.
- Refactor an toàn: đổi tên hoặc cấu trúc dữ liệu, trình biên dịch chỉ ra mọi chỗ cần sửa.
- Tài liệu sống: kiểu dữ liệu mô tả rõ hàm nhận gì, trả gì.
- Phổ biến: nhiều framework như Angular, NestJS dùng TypeScript mặc định; React, Vue, Next.js đều hỗ trợ tốt.
TypeScript và JavaScript khác nhau thế nào?
| Tiêu chí | JavaScript | TypeScript |
|---|---|---|
| Kiểu dữ liệu | Động, kiểm tra khi chạy | Tĩnh, kiểm tra khi biên dịch |
| Chạy trực tiếp | Có | Cần biên dịch sang JavaScript (một số runtime hỗ trợ chạy trực tiếp) |
| Phát hiện lỗi | Thường khi chạy | Ngay khi viết code |
| Đường cong học | Thấp hơn | Cần học thêm hệ thống kiểu |
| Phù hợp | Script nhỏ, prototype nhanh | Dự án vừa và lớn, làm việc nhóm |
Mọi code JavaScript hợp lệ về cơ bản đều là TypeScript hợp lệ, nên bạn có thể chuyển đổi dần dự án cũ thay vì viết lại.
Cài đặt và chạy TypeScript
npm install -D typescript
npx tsc --init # tạo file tsconfig.json
npx tsc # biên dịch sang JavaScript
Trong tsconfig.json, hãy bật "strict": true ngay từ đầu. Chế độ strict bật các kiểm tra quan trọng như cấm any ngầm định và bắt buộc xử lý null/undefined.
Các kiểu dữ liệu cơ bản
let ten: string = "MelyDemy";
let gia: number = 29000;
let daXuatBan: boolean = true;
let tags: string[] = ["react", "typescript"];
let toaDo: [number, number] = [10, 20]; // tuple
let maKhoa: string | number = "ts1"; // union type
let trangThai: "draft" | "published" = "draft"; // literal type
any: tắt kiểm tra kiểu, nên tránh.unknown: an toàn hơnany, buộc kiểm tra trước khi dùng.void: hàm không trả về giá trị;never: hàm không bao giờ kết thúc bình thường.
TypeScript cũng có khả năng suy luận kiểu: let gia = 29000 tự hiểu là number, nên bạn không cần khai báo kiểu ở mọi nơi.
Interface và type
interface KhoaHoc {
id: number;
ten: string;
gia: number;
moTa?: string; // thuộc tính tuỳ chọn
readonly slug: string; // chỉ đọc
}
type HocVien = {
id: number;
ten: string;
khoaHoc: KhoaHoc[];
};
function hienThi(k: KhoaHoc) {
return `${k.ten} - ${k.gia.toLocaleString("vi-VN")}₫`;
}
interface và type đều mô tả hình dạng object. Quy ước phổ biến: dùng interface cho object có thể mở rộng, dùng type cho union, tuple hoặc kiểu phức hợp. Quan trọng nhất là thống nhất trong dự án.
Generic – viết code tái sử dụng có kiểu
interface ApiResponse<T> {
data: T;
error?: string;
}
async function getJson<T>(url: string): Promise<ApiResponse<T>> {
const res = await fetch(url);
return res.json();
}
const ketQua = await getJson<KhoaHoc[]>("/api/courses");
ketQua.data[0].ten; // editor biết đây là string
Generic giống như “tham số cho kiểu”, giúp một hàm hoặc interface làm việc với nhiều kiểu dữ liệu mà vẫn giữ được kiểm tra chặt chẽ.
Utility type hay dùng
| Utility | Tác dụng | Ví dụ |
|---|---|---|
Partial<T> | Mọi thuộc tính thành tuỳ chọn | Dữ liệu form cập nhật |
Pick<T, K> | Chọn một số thuộc tính | Pick<KhoaHoc, "id" | "ten"> |
Omit<T, K> | Bỏ một số thuộc tính | Dữ liệu tạo mới không có id |
Record<K, V> | Object với key và value xác định | Record<string, number> |
Required<T> / Readonly<T> | Bắt buộc / chỉ đọc mọi thuộc tính | Cấu hình đã xác thực |
Thu hẹp kiểu (type narrowing)
function inMa(ma: string | number) {
if (typeof ma === "string") {
return ma.toUpperCase(); // ở đây ma là string
}
return ma.toFixed(0); // ở đây ma là number
}
TypeScript hiểu các phép kiểm tra như typeof, instanceof, in và so sánh với giá trị cụ thể để tự thu hẹp kiểu trong từng nhánh.
TypeScript với React
type Props = {
khoaHoc: KhoaHoc;
onDangKy: (id: number) => void;
};
export function CourseCard({ khoaHoc, onDangKy }: Props) {
const [daChon, setDaChon] = useState<boolean>(false);
return (
<button onClick={() => { setDaChon(true); onDangKy(khoaHoc.id); }}>
{daChon ? "Đã chọn" : khoaHoc.ten}
</button>
);
}
Khi dùng TypeScript, quên truyền props hoặc truyền sai kiểu sẽ báo lỗi ngay. Xem thêm ReactJS là gì và lộ trình học React, hoặc khoá học ReactJS.
TypeScript ở backend
TypeScript cũng rất phổ biến phía server với Node.js. Framework NestJS dùng TypeScript mặc định; Express cũng có thể dùng kèm TypeScript. Dùng chung kiểu dữ liệu giữa frontend và backend giúp giảm lỗi khi hai bên giao tiếp qua API. Xem lộ trình học backend.
Khi nào nên học TypeScript?
Hãy học TypeScript sau khi đã vững JavaScript cơ bản: biến, hàm, object, mảng, Promise. Nếu học TypeScript quá sớm, bạn sẽ phải xử lý cùng lúc logic lập trình và hệ thống kiểu, dễ nản. Thứ tự gợi ý nằm trong lộ trình học lập trình web cho người mới.
Sai lầm thường gặp
- Dùng
anykhắp nơi để “cho hết lỗi”, làm mất ý nghĩa của TypeScript. - Lạm dụng ép kiểu
asthay vì kiểm tra dữ liệu thật. - Tin tưởng tuyệt đối kiểu của dữ liệu từ API: kiểu chỉ tồn tại lúc biên dịch, dữ liệu từ bên ngoài vẫn cần được kiểm tra khi chạy (có thể dùng thư viện như Zod).
- Viết kiểu quá phức tạp khiến code khó đọc.
Chuyển dự án JavaScript sang TypeScript
Không cần viết lại toàn bộ dự án. Bạn có thể chuyển dần theo các bước:
- Cài TypeScript, tạo
tsconfig.jsonvớiallowJs: trueđể file JS và TS cùng tồn tại. - Đổi đuôi từng file từ
.jssang.ts(hoặc.jsxsang.tsx), bắt đầu từ file tiện ích ít phụ thuộc. - Thêm kiểu cho dữ liệu quan trọng nhất trước: dữ liệu từ API, props của component, tham số hàm dùng chung.
- Cài gói kiểu cho thư viện chưa có sẵn (thường là
@types/ten-thu-vien). - Bật dần các tuỳ chọn strict khi số lỗi đã giảm.
Cách làm này giúp dự án vẫn chạy bình thường trong suốt quá trình chuyển đổi.
Kiểm tra dữ liệu khi chạy với Zod
Kiểu TypeScript chỉ tồn tại lúc biên dịch. Dữ liệu đến từ API, form hoặc file cấu hình vẫn có thể sai khi chạy. Thư viện như Zod cho phép khai báo schema một lần, vừa kiểm tra dữ liệu thật, vừa sinh ra kiểu TypeScript tương ứng:
import { z } from "zod";
const KhoaHocSchema = z.object({
id: z.number(),
ten: z.string().min(1),
gia: z.number().nonnegative(),
});
type KhoaHoc = z.infer<typeof KhoaHocSchema>;
const data = KhoaHocSchema.parse(await res.json()); // báo lỗi nếu dữ liệu sai
Cách này giúp “ranh giới” giữa ứng dụng và thế giới bên ngoài an toàn hơn, đặc biệt ở backend khi nhận dữ liệu từ người dùng.
Câu hỏi thường gặp
TypeScript có khó học không?
Nếu đã biết JavaScript, phần cơ bản của TypeScript khá dễ tiếp cận. Các khái niệm nâng cao như generic phức tạp, conditional type cần thời gian luyện tập thêm.
TypeScript có làm ứng dụng chạy chậm hơn không?
Không đáng kể khi chạy, vì TypeScript được biên dịch thành JavaScript và phần kiểu bị loại bỏ. Chỉ thời gian build có thể tăng.
Có cần học JavaScript trước TypeScript không?
Nên. TypeScript là JavaScript cộng thêm kiểu, nên hiểu JavaScript giúp bạn học TypeScript nhanh và đúng bản chất.
Dự án nhỏ có cần TypeScript không?
Không bắt buộc. Với script ngắn hoặc prototype, JavaScript là đủ. TypeScript phát huy giá trị rõ nhất ở dự án lâu dài, nhiều người cùng làm.
Kết luận
TypeScript giúp code JavaScript an toàn, dễ bảo trì và làm việc nhóm hiệu quả hơn nhờ hệ thống kiểu tĩnh. Hãy bắt đầu với chế độ strict, học các kiểu cơ bản, interface, generic, rồi áp dụng vào dự án React hoặc Node.js. Để học bài bản, tham khảo khoá học TypeScript từ cơ bản đến thực chiến và nền tảng khoá học JavaScript của MelyDemy.