Ở bài viết trước khi mình giới thiệu về TypeScript, chúng ta đã hiểu phần nào về ngôn ngữ lập trình hiện đại này. Ngày nay, rất nhiều nền tảng, framework từ backend tới front end hầu hết đều đã hỗ trợ Typescript. Điều đó cho thấy sức hút của ngôn ngữ này như thế nào đúng không?
Có lẽ không cần phân tích lại những ưu điểm và nhược điểm của TypeScript nữa, bạn có thể tham khảo trong bài viết trước của mình.
👍 Tham khảo: Ưu điểm và nhược điểm của TypeScript và cách cài đặt TypeScript
Bài viết hôm này, chúng ta sẽ cùng nhau học những cú pháp và tính năng mà TypeScript cung cấp, những điều mà TypeScript mang lại mà Javascript thuần không có.
Chúng ta bắt đầu thôi!
Nội dung chính của bài viết
Những Text Editor hỗ trợ TypeScript
TypeScript là một dự án mã nguồn mở và được ông trùm phần mềm Microsoft duy trì và phát triển.
Có rất nhiều Text Editor hỗ trợ để bạn code TypeScript một cách ngon lành. Trong những cái tên phổ biến, mình luôn dành sự ưu ái cho Visual Studio Code của Microsoft. Nếu bạn không thích Visual Code thì có thể đổi gió sang Subline Text , cũng rất thú vị. Trên VNTALKING, mình đều đã giới thiệu cả hai Text Editor này, mời bạn tham khảo.
- Cài đặt Visual studio code – Cách sử dụng toàn tập
- Debug Typescript trên Visual Code
- Sublime Text 3 – Code Editor nhỏ mà có “võ”
Về môi trường để có thể code Typescript cơ bản là như vậy. Chúng ta cùng bắt tay vào tìm hiểu TypeScript thôi nhỉ.
Type (kiểu dữ liệu) trong TypeScript
Học Typescript mà lại không biết về kiểu (type) của nó thì thật là thiếu sót. Vậy Type là gì?
Theo định nghĩa mà nhiều chuyên gia thống nhất rằng:
Hiểu nôm na là: Type là một tập các giá trị cùng loại và những điều mà bạn có thể làm với chúng.
Tất nhiên, các định nghĩa trong ngành IT nói riêng, kỹ thuật nói chung luôn luôn khá khó hiểu nếu chỉ thuần đọc định nghĩa. Mình sẽ lấy ví dụ cho bạn dễ hiểu:
- Kiểu Boolean là tập hợp các giá trị chỉ có 2 loại:
true
hoặcfalse
và các thao tác mà bạn có thể thực hiện trên chúng như:||, && và !
- Kiểu Number là tập hợp tất cả số (cả âm và dương) và các phép toán mà có thể thực hiện như: cộng, trừ, nhân, chia…
Trong bài viết này, chúng ta sẽ xem xét các Type được hỗ trợ sẵn trong Typescript. Để có cái nhìn tổng quan, mời bạn hãy nhìn sơ đồ các Type ở hình bên dưới đây.
Ví dụ cách định nghĩa type trong Typescript:
// boolean let isDone: boolean = false; // number let decimal: number = 6; // string let color: string = "blue"; color = 'red'; // Array let list: number[] = [1, 2, 3]; //enum enum Color { Red, Green, Blue, } let c: Color = Color.Green;
Tóm lại, Typescript được xây dựng đi kèm với một loạt các kiểu dữ liệu. Bạn có thể để typescript tự nhận biết kiểu của một giá trị hoặc bạn chỉ định sẵn từ trước.
Function – Hàm
Trong Javascript, các function được coi là Object, điều đó có nghĩa là bạn có thể làm việc với chúng như đang làm việc với Object vậy. Ví dụ: gán function vào một biến, chuyền function vào trong một function khác, một function có thể return trả về một function.v.v…
Trong Typescript đã mô hình hóa tất cả những thứ đó với hệ thống Type mà mình đã trình bày ở phần trên bài viết.
Ví dụ một function được định nghĩa trong Typescript sẽ như sau:
function add(a: number, b: number) { return a + b; }
Như bạn thấy trong ví dụ trên, các tham số đều được định nghĩa kiểu dữ liệu rõ ràng, thay vì chỉ là hai Arguments chung chung.
Tương tự Javascript, trong typescript bạn có nhiều cách để định nghĩa một function:
// Named function function greet(name: string) { return 'hello ' + name; } // Function expression let greet2 = function (name: string) { return 'hello ' + name; }; // Arrow function expression let greet3 = (name: string) => { return 'hello ' + name; }; // Shorthand arrow function expression let greet4 = (name: string) => 'hello ' + name; // Function constructor let greet5 = new Function('name', 'return "hello " + name');
Khi đã định nghĩa kiểu dữ liệu tường minh như trên, khi bạn gọi hàm và truyền sai kiểu, lập tức trình compile của Typescript sẽ phát hiện và báo lỗi ngay. Rất thú vị phải không!?
add(1) // Error TS2554: Expected 2 arguments, but got 1. add(1, 'a') // Error TS2345: Argument of type '"a"' is not assignable // to parameter of type 'number'.
Classes và Interfaces
Nếu bạn để ý, ngày càng nhiều nền tảng hay framework đã hỗ trợ Typescript, có lẽ mục đích của nó là để thỏa mãn nhu cầu của các developer, đó là nhu cầu lập trình hướng đối tượng bằng các ngôn ngữ kiểu script. Kể cũng dị nhỉ.
Mà nói tới lập trình hướng đối tượng (OOP) thì Class và Interface là hai khái niệm “linh hồn” không thể thiếu.
Trong Typescript, chúng ta cũng có khái niệm class, cũng có kế thừa (bằng từ khóa extend), cũng có interface luôn. Ví dụ, chúng ta định nghĩa các class chung là bàn cờ, vị trí, quân cờ:
// Represents a chess game class Game {} // A chess piece class Piece {} // A set of coordinates for a piece class Position {}
Sau đó, định nghĩa cụ thể các quân cờ như: tượng, mã, xe… bằng cách kế thừa:
// ... class King extends Piece {} class Queen extends Piece {} class Bishop extends Piece {} class Knight extends Piece {} class Rook extends Piece {} class Pawn extends Piece {}
Khi sử dụng Class, chúng ta thường sẽ sử dụng chúng cùng với Interface. Không giống với Class, Interface là một cấu trúc ảo, một khái niệm chỉ có trong Typescript.
Trong Typescript, chúng ta thường sử dụng interface chỉ để kiểm tra kiểu.
Ví dụ chúng ta có đoạn code sau:
class PizzaMaker { create(event: { name: string; toppings: string[] }) { return { name: event.name, toppings: event.toppings }; } }
Thay vì phải định nghĩa rõ ràng cấu trúc của tham số truyền vào event là: { name: string; toppings: string[] }
chúng ta có thể sử dụng Interface để thay thế:
interface Pizza { name: string; toppings: string[]; } class PizzaMaker { static create(event: Pizza) { return { name: event.name, toppings: event.toppings }; } }
Và khi gọi hàm create
, chúng ta làm như sau:
const pizza = PizzaMaker.create({ name: 'Inferno', toppings: ['cheese', 'peppers'] });
Như vậy là params truyền vào là một object sẽ tự động ép kiểu thành Pizza, nên bạn hoàn toàn có thể thoải mái truy xuất vào hai thuộc tính name và toppings
Implement Interface
Tuy nhiên, Interface trong Typescript không chỉ có vậy. Khi bạn khai báo một class và sử dụng từ khóa implement để nói rằng class đó thực thi một interface cụ thể. Nếu bạn đã từng làm việc với Java, C#… thì sẽ biết Interface là một cách để triển khai triết lý đa hình trong OOP. Cùng xem ví dụ sau nhé:
interface Animal { talk(): void; } class Cat implements Animal { talk() { console.info('Meo meo'); } } class Dog implements Animal { talk() { console.info('Gâu Gâu'); } } let milu = new Cat(); milu.talk(); // Kết quả: "Meo Meo" let jeck = new Dog(); jeck.talk(); // kết quả: "Gâu Gâu"
Hôm nay mình tạm thời kết thúc bài viết học Typescript ở đây, tất nhiên là mình sẽ còn nhiều bài viết về Typescript này nữa. Nếu bạn có hứng thú với Typescript hoặc đang theo học series Angular 2 với Typescript cùng mình thì comment bên dưới nhé.
Bình luận. Cùng nhau thảo luận nhé!