Interface trong Typescript
Trong bài viết này, mình sẽ tìm hiểu về Interface trong TypeScript và các khía cạnh quan trọng của nó. Mình sẽ bắt đầu bằng việc tìm hiểu về các Optional Properties (Thuộc tính tùy chọn) trong Interface, sau đó tìm hiểu cách sử dụng thuộc tính readonly (chỉ đọc). Tiếp theo, sẽ so sánh sự khác nhau giữa const và readonly, hai khái niệm quan trọng trong TypeScript. Cuối cùng, mình sẽ nghiên cứu Function Types (Kiểu hàm) trong Interface và cách chúng có thể được áp dụng trong thực tế.
Hãy cùng bắt đầu hành trình khám phá Interface và các tính năng quan trọng liên quan đến nó trong TypeScript.
Interface trong TypeScript là gì?
Interface trong TypeScript là một khái niệm quan trọng cho phép bạn định nghĩa cấu trúc dữ liệu và hành vi của đối tượng. Nó là một cách để mô tả các kiểu dữ liệu và hành vi mà các đối tượng cụ thể cần tuân thủ. Interface giúp bạn kiểm tra và đảm bảo tính đúng đắn của mã nguồn.
Một Interface định nghĩa các thuộc tính và phương thức mà một đối tượng cần phải cung cấp. Khi một đối tượng triển khai một Interface, nó phải tuân thủ tất cả các yêu cầu được đặt ra bởi Interface đó.
Bài viết này được đăng tại [free tuts .net]
Ví dụ, bạn có thể định nghĩa một Interface "Person" với các thuộc tính như "name" và "age." Khi bạn tạo một đối tượng và khai báo rằng nó tuân thủ Interface "Person," đối tượng đó phải cung cấp đầy đủ thông tin về "name" và "age."
Dưới đây là một ví dụ cơ bản về cách định nghĩa một Interface trong TypeScript:
interface Person { name: string; age: number; } const user: Person = { name: "John", age: 30 };
Interface là một công cụ mạnh mẽ giúp bạn xây dựng mã TypeScript đáng tin cậy và dễ bảo trì.
Optional Properties trong Interface
Định nghĩa và sử dụng Optional Properties
Trong TypeScript, bạn có khả năng định nghĩa các thuộc tính tùy chọn trong một Interface. Điều này có nghĩa rằng các thuộc tính đó có thể tồn tại hoặc không tồn tại trong đối tượng tuân thủ Interface, và bạn không bắt buộc phải cung cấp chúng khi tạo đối tượng.
Cú pháp để định nghĩa một thuộc tính tùy chọn trong một Interface là sử dụng dấu hỏi sau tên thuộc tính:
interface Person { name: string; age?: number; // Thuộc tính "age" là tùy chọn }
Thuộc tính "age" ở trên là một thuộc tính tùy chọn, tức là bạn có thể tạo một đối tượng "Person" mà không cần cung cấp giá trị cho thuộc tính "age."
Ví dụ minh họa
Dưới đây là một ví dụ minh họa về việc sử dụng thuộc tính tùy chọn trong một Interface:
interface Person { name: string; age?: number; } const person1: Person = { name: "Alice" }; // Không cần cung cấp "age" const person2: Person = { name: "Bob", age: 30 }; // Cung cấp cả "name" và "age"
Trong ví dụ này, "person1" không cung cấp giá trị cho thuộc tính "age," trong khi "person2" cung cấp cả "name" và "age." Interface "Person" cho phép bạn linh hoạt trong việc xác định đối tượng tuân thủ Interface, và chỉ yêu cầu cung cấp những thuộc tính quan trọng và tùy ý.
Thuộc tính readonly trong Interface
Định nghĩa và sử dụng thuộc tính readonly
Trong TypeScript, bạn có khả năng định nghĩa các thuộc tính "chỉ đọc" trong một Interface. Thuộc tính "chỉ đọc" chỉ có thể được đọc và không thể bị ghi đè sau khi được gán giá trị ban đầu.
Để định nghĩa một thuộc tính "chỉ đọc," bạn sử dụng từ khóa "readonly" trước tên thuộc tính:
interface Book { title: string; readonly author: string; // Thuộc tính "author" là chỉ đọc }
Ví dụ minh họa
Dưới đây là một ví dụ minh họa về việc sử dụng thuộc tính "chỉ đọc" trong một Interface:
interface Book { title: string; readonly author: string; } const book: Book = { title: "The Great Gatsby", author: "F. Scott Fitzgerald" }; // Bạn có thể đọc giá trị của thuộc tính "author" console.log(book.author); // In ra: "F. Scott Fitzgerald" // Nhưng bạn không thể ghi đè lên giá trị của thuộc tính "author" // book.author = "Another Author"; // Lỗi biên dịch
Trong ví dụ này, thuộc tính "author" trong Interface "Book" là thuộc tính "chỉ đọc," nên sau khi được gán giá trị ban đầu, bạn không thể thay đổi giá trị của nó.
Sự khác nhau giữa const và readonly
Giải thích sự khác nhau giữa const và readonly
Sự khác nhau chính giữa "const" và "readonly" là:
-
"const" được sử dụng để khai báo một hằng số (constant) trong phạm vi một biến, trong khi "readonly" được sử dụng để khai báo một thuộc tính "chỉ đọc" trong một Interface hoặc lớp (class).
-
"const" áp dụng cho biến, nghĩa là bạn không thể thay đổi giá trị của biến sau khi nó đã được gán giá trị. Trong trường hợp của "readonly," nó áp dụng cho thuộc tính trong Interface hoặc lớp, nghĩa là bạn không thể thay đổi giá trị của thuộc tính sau khi nó đã được gán giá trị ban đầu.
-
"const" được sử dụng trong phạm vi biến, còn "readonly" được sử dụng trong phạm vi Interface hoặc lớp.
Ví dụ minh họa
Dưới đây là một ví dụ minh họa để giải thích sự khác nhau giữa "const" và "readonly":
// Sử dụng "const" để khai báo một hằng số const PI = 3.14159; // Bạn không thể thay đổi giá trị của "PI" // PI = 3.14; // Lỗi biên dịch // Sử dụng "readonly" để khai báo một thuộc tính "chỉ đọc" trong Interface interface Circle { readonly radius: number; } const circle: Circle = { radius: 5 }; // Bạn không thể thay đổi giá trị của thuộc tính "radius" // circle.radius = 10; // Lỗi biên dịch
Trong ví dụ này, "const" được sử dụng để khai báo một biến hằng số "PI," trong khi "readonly" được sử dụng để khai báo một thuộc tính "chỉ đọc" trong Interface "Circle." Bạn không thể thay đổi giá trị của "PI" hoặc thuộc tính "radius" sau khi chúng đã được gán giá trị ban đầu.
Function Types trong Interface
Định nghĩa và sử dụng Function Types trong Interface
Trong TypeScript, bạn có thể sử dụng Function Types để định nghĩa kiểu dữ liệu cho một hàm. Điều này rất hữu ích khi bạn muốn mô tả kiểu của một hàm, bao gồm kiểu của tham số và kiểu trả về.
Để định nghĩa Function Types trong Interface, bạn sử dụng cú pháp sau:
interface MyFunction { (param1: number, param2: string): boolean; }
Trong ví dụ này, "MyFunction" là một Function Type trong Interface. Nó mô tả một hàm có hai tham số: một số nguyên và một chuỗi, và trả về một giá trị boolean.
Ví dụ minh họa
Dưới đây là một ví dụ minh họa về cách sử dụng Function Types trong Interface:
interface Calculator { (a: number, b: number): number; } function add(a: number, b: number): number { return a + b; } function subtract(a: number, b: number): number { return a - b; } const calculator: Calculator = add; console.log(calculator(5, 3)); // Kết quả: 8 const anotherCalculator: Calculator = subtract; console.log(anotherCalculator(10, 4)); // Kết quả: 6
Trong ví dụ này, mình đã định nghĩa một Interface "Calculator" với một Function Type mô tả hàm có hai tham số số nguyên và trả về một số nguyên. Sau đó, mình đã tạo hai hàm "add" và "subtract" có cùng kiểu với "Calculator" và gán chúng vào biến "calculator" và "anotherCalculator." Ta có thể sử dụng các biến này để gọi các hàm tương ứng.
Trong phần 1 của bài viết, mình đã tìm hiểu về các khái niệm cơ bản của Interface trong TypeScript, bao gồm Optional Properties, thuộc tính readonly, Function Types, Indexable Types và cách kế thừa Interfaces. Đây là những khái niệm quan trọng để bạn có thể sử dụng Interface một cách hiệu quả trong TypeScript. Chúng ta sẽ tiếp tục với phần 2 để tìm hiểu về Class Types và kiểu hỗn hợp (Hybrid Types).