Tạo một hàm đơn giản
Trong tutorial này, qua trải nghiệm tạo một hàm đơn giản với TypeScript, bạn sẽ học type của TypeScript giải quyết vấn đề gì của JavaScript và compiler đóng vai trò gì.
Những thứ cần thiết cho tutorial này
Để thực hiện tutorial này, cần có một số tool. Hãy chuẩn bị những thứ được liệt kê dưới đây.
- Node.js
- Editor như VS Code hoặc WebStorm
- tsc (TypeScript compiler)
📄️ Chuẩn bị môi trường code
Hãy cài đặt Node.js, TypeScript compiler và editor cần thiết cho phát triển TypeScript.
Vấn đề có thể xảy ra với JavaScript
Đầu tiên, hãy tạo file JavaScript sau ở môi trường local.
increment.jsjsfunction increment(num) {return num + 1;}console.log(increment(999));
increment.jsjsfunction increment(num) {return num + 1;}console.log(increment(999));
Chương trình này chỉ increment argument và trả về. Hãy thử chạy với Node.js.
sh$ node increment.js1000
sh$ node increment.js1000
Chắc là chạy không có vấn đề gì. Tiếp theo, hãy thay đổi argument của hàm increment từ 999 sang string "999".
increment.jsjsfunction increment(num) {return num + 1;}console.log(increment("999"));// ^^^^^
increment.jsjsfunction increment(num) {return num + 1;}console.log(increment("999"));// ^^^^^
Thay đổi nhỏ này làm kết quả thực thi thay đổi lớn. Hãy thử chạy.
sh$ node increment.js9991
sh$ node increment.js9991
Kết quả output chắc đã thay đổi từ 1000 sang 9991. Lý do là vì argument num trở thành string, toán tử + không còn là phép cộng mà trở thành nối chuỗi. JavaScript hiểu "999" + 1 thành "999" + "1". Để biết chi tiết về cách hiểu này, hãy xem giải thích về type coercion.
📄️ Type coercion
JavaScript có data type, nhưng có những trường hợp khi thực hiện phép toán với hai giá trị khác kiểu mà không gây lỗi. Ví dụ, khi trừ kiểu number 1 từ kiểu string "1", kết quả là kiểu number 0.
Argument chỉ khác nhau về type một cách tinh tế giữa 999 và "999". Nếu đây là tính toán số tiền thì sẽ là vấn đề lớn. Hàm increment chỉ hoạt động đúng khi argument num là kiểu number. Tuy nhiên, khi gọi hàm, có thể truyền nhiều type khác nhau mà không có ràng buộc. Làm thế nào để ràng buộc chỉ có thể gán kiểu number cho argument? Đây là lúc TypeScript xuất hiện.
Chuyển đổi JavaScript sang TypeScript
Bước đầu tiên để biến JavaScript thành TypeScript là đổi extension của file từ .js sang .ts. TypeScript nói đơn giản là ngôn ngữ chỉ thêm cú pháp liên quan đến type vào JavaScript. Vì vậy, code JavaScript có thể được xử lý như TypeScript nguyên vẹn.
shmv increment.js increment.ts
shmv increment.js increment.ts
Làm compiler hoạt động
Tính năng nổi bật của TypeScript chính là compiler. Một trong những vai trò của compiler là kiểm tra vấn đề về type như ví dụ trên và báo cáo các điểm phát hiện cho programmer. TypeScript compiler rất thông minh, có thể chỉ ra vấn đề về type mà không cần gợi ý. Tuy nhiên, nếu cho đủ gợi ý, compiler sẽ kiểm tra tỉ mỉ hơn.
Gợi ý cho compiler được gọi là "type annotation". Vậy hãy viết type annotation cho argument num của hàm increment. Type annotation được viết là : number bên phải num. Viết điều này có nghĩa là "argument num chỉ có thể gán kiểu number". Compiler sẽ dựa vào gợi ý này để kiểm tra code gọi hàm.
increment.tstsfunctionincrement (num : number) {// ^^^^^^^^type annotationreturnnum + 1;}console .log (increment ("999"));
increment.tstsfunctionincrement (num : number) {// ^^^^^^^^type annotationreturnnum + 1;}console .log (increment ("999"));
Sau khi viết type annotation, hãy để TypeScript compiler kiểm tra. Lệnh của TypeScript compiler là tsc.
shtsc increment.ts
shtsc increment.ts
Sẽ có error sau được báo cáo.
tsArgument of type 'string' is not assignable to parameter of type 'number'.2345Argument of type 'string' is not assignable to parameter of type 'number'.console .log (increment ("999" ));
tsArgument of type 'string' is not assignable to parameter of type 'number'.2345Argument of type 'string' is not assignable to parameter of type 'number'.console .log (increment ("999" ));
Nội dung error này là chỉ ra rằng "argument num chỉ có thể gán kiểu number, nhưng khi gọi hàm lại gán kiểu string. Liệu có thực sự không có vấn đề gì?".
Error có thể có hình ảnh là thứ không mong muốn. Tuy nhiên, error mà compiler báo cáo là thứ được hoan nghênh. Bởi vì nó thay bạn thông báo về nguy hiểm tiềm ẩn trong code tại thời điểm coding.
Vượt qua compile
Công việc giải quyết tất cả các điểm vấn đề mà compiler chỉ ra được gọi là "vượt qua compile". Hãy sửa code trên thành code có thể vượt qua compile. Cách sửa đơn giản là chỉ cần biến argument khi gọi hàm thành kiểu number.
increment.tstsfunctionincrement (num : number) {returnnum + 1;}console .log (increment (999));// ^^^chỗ cần sửa
increment.tstsfunctionincrement (num : number) {returnnum + 1;}console .log (increment (999));// ^^^chỗ cần sửa
Sau khi sửa, hãy compile lại.
shtsc increment.ts
shtsc increment.ts
Lần này chắc xử lý kết thúc mà không hiển thị gì. Compile thành công.
JavaScript được tạo ra
Bạn có thể đã nhận ra rằng qua các bước đến đây, một file increment.js đã được tạo ra. Nội dung của file đó chắc như sau.
increment.jstsfunction increment(num) {return num + 1;}console.log(increment(999));
increment.jstsfunction increment(num) {return num + 1;}console.log(increment(999));
Đây là file JavaScript được compiler tạo ra trong quá trình compile increment.ts. So sánh với code TypeScript, bạn có thể thấy type annotation đã bị xóa khỏi argument num.
Phần type annotation là thứ riêng của TypeScript. Nếu có nó thì không thể thực thi trên browser hoặc Node.js. Vì vậy, TypeScript compiler tạo ra file JavaScript để chạy trên môi trường thực thi JavaScript. Developer sẽ deploy file JavaScript thành phẩm này lên môi trường production.
Chia sẻ kiến thức
・Viết lại từ JavaScript sang TypeScript là đổi extension thành .ts
・Compiler cho biết vấn đề về type
・Thêm type annotation giúp compiler kiểm tra chi tiết hơn
・Deploy và sử dụng JS được compiler tạo ra
Từ 『Survival TypeScript』