Trong hướng dẫn này, bạn sẽ tìm hiểu về các kiểu dữ liệu trong TypeScript và mục đích của chúng.
Trong TypeScript, một kiểu dữ liệu là một cách thuận tiện để tham chiếu đến các thuộc tính và hàm khác nhau của một giá trị.
Giá trị là bất kỳ giá trị nào mà bạn có thể gán cho một biến, ví dụ: một số, một chuỗi, một mảng, một đối tượng và một hàm.
Xem giá trị sau:
'Hello'
Khi bạn nhìn vào giá trị này, bạn có thể nói rằng đó là một chuỗi. Và giá trị này có các thuộc tính và phương thức mà một chuỗi có.
Ví dụ: giá trị 'Hello'
có một thuộc tính được gọi là length
trả về số lượng ký tự trong chuỗi:
console.log('Hello'.length); // 5
Nó cũng có nhiều phương thức như match()
, indexOf()
, và toLocaleUpperCase()
. Ví dụ:
console.log('Hello'.toLocaleUpperCase()); // HELLO
Nếu bạn nhìn vào giá trị 'Hello'
và mô tả nó bằng cách liệt kê các thuộc tính và phương thức, sẽ rất bất tiện.
Một cách ngắn hơn để tham chiếu đến một giá trị là gán cho nó một kiểu dữ liệu. Trong ví dụ này, bạn nói rằng 'Hello'
là một chuỗi. Sau đó, bạn biết rằng bạn có thể sử dụng các thuộc tính và phương thức của một chuỗi cho giá trị 'Hello'
.
Tóm lại, trong TypeScript:
TypeScript kế thừa các kiểu dữ liệu được tích hợp sẵn trong JavaScript. Các kiểu dữ liệu trong TypeScript được phân loại thành:
Bảng sau đây minh họa các kiểu dữ liệu nguyên thủy trong TypeScript:
Tên | Miêu tả |
---|---|
string |
Đại diện cho dữ liệu văn bản |
number |
Đại diện cho các giá trị số |
boolean
|
Có giá trị true và false |
null
|
Có một giá trị: null |
undefined
|
Có một giá trị: undefined . Nó là một giá trị mặc định của một biến chưa được khởi tạo (gán giá trị) |
symbol
|
Đại diện cho một giá trị hằng số duy nhất |
Các kiểu dữ liệu đối tượng là các hàm, mảng, lớp, v.v. Sau đó, bạn sẽ học cách tạo các loại đối tượng tùy chỉnh.
Có hai mục đích chính của các kiểu dữ liệu trong TypeScript:
Ví dụ sau sử dụng phương thức querySelector()
để chọn phần tử <h1>
:
const heading = document.querySelector('h1');
Trình biên dịch TypeScript biết rằng kiểu dữ liệu của heading
là HTMLHeadingElement
:
Và nó hiển thị danh sách các phương thức thuộc kiểu dữ liệu HTMLHeadingElement
mà heading
có thể truy cập:
Nếu bạn cố gắng truy cập thuộc tính hoặc phương thức không tồn tại, trình biên dịch TypeScript sẽ hiển thị lỗi. Ví dụ:
TypeScript sử dụng các chú thích kiểu dữ liệu (Type Annotation) để chỉ định rõ ràng kiểu dữ liệu cho biến, hàm, đối tượng, v.v.
TypeScript sử dụng cú pháp : type
ngay sau mã định danh để làm chú thích kiểu dữ liệu, trong đó type
có thể là bất kỳ kiểu dữ liệu hợp lệ nào.
Sau khi một mã định danh được chú thích bằng một kiểu dữ liệu, nó chỉ có thể được sử dụng với kiểu dữ liệu đó. Nếu mã định danh được sử dụng như một kiểu dữ liệu khác, trình biên dịch TypeScript sẽ báo lỗi.
Cú pháp sau cho thấy cách chỉ định chú thích kiểu dữ liệu cho biến và hằng số:
let variableName: type;
let variableName: type = value;
const constantName: type = value;
Trong cú pháp này, chú thích kiểu dữ liệu đứng ngay sau tên biến hoặc hằng số và bắt đầu bằng dấu hai chấm (:
).
Ví dụ sau sử dụng chú thích kiểu dữ liệu number
cho một biến:
let counter: number;
Sau đó, bạn chỉ có thể gán một giá trị kiểu số cho biến counter
:
counter = 1;
Nếu bạn gán một giá trị kiểu chuỗi cho biến counter
, bạn sẽ gặp lỗi:
let counter: number;
counter = 'Hello'; // compile error
Lỗi:
Type '"Hello"' is not assignable to type 'number'.
Bạn có thể vừa sử dụng chú thích kiểu dữ liệu cho một biến vừa khởi tạo giá trị cho nó trong cùng một câu lệnh như sau:
let counter: number = 1;
Trong ví dụ này, chúng tôi sử dụng chú thích kiểu số cho biến counter
và gán giá trị 1 cho nó.
Sau đây là các ví dụ khác về chú thích kiểu dữ liệu nguyên thủy:
let name: string = 'John';
let age: number = 25;
let active: boolean = true;
Trong ví dụ này, biến name
có kiểu dữ liệu là string
, biến age
có kiểu dữ liệu là number
và biến active
có kiểu dữ liệu là boolean
.
Để chú thích một kiểu mảng, bạn sử dụng một kiểu dữ liệu cụ thể và theo sau bởi một cặp dấu ngoặc vuông như sau : type[]
.
let arrayName: type[];
Ví dụ, phần sau khai báo một mảng kiểu chuỗi:
let names: string[] = ['John', 'Jane', 'Peter', 'David', 'Mary'];
Để chỉ định kiểu dữ liệu cho một đối tượng, bạn sử dụng chú thích kiểu dữ liệu đối tượng. Ví dụ:
let person: {
name: string;
age: number
};
person = {
name: 'John',
age: 25
}; // valid
Trong ví dụ này, đối tượng person
chỉ chấp nhận một đối tượng có hai thuộc tính là: name
có kiểu string
và age
có kiểu number
.
Phần sau trình bày chú thích hàm với chú thích kiểu dữ liệu tham số và chú thích kiểu dữ liệu trả về:
let greeting : (name: string) => string;
Trong ví dụ này, bạn có thể gán bất kỳ hàm nào chấp nhận một tham số đầu vào kiểu chuỗi và trả về kiểu chuỗi cho biến greeting
:
greeting = function (name: string) {
return `Hi ${name}`;
};
Ví dụ sau đây gây ra lỗi vì hàm được gán cho biến greeting
không khớp với định nghĩa của nó.
greeting = function () {
console.log('Hello');
};
Lỗi:
Type '() => void' is not assignable to type '(name: string) => string'. Type 'void' is not assignable to type 'string'.
Suy luận kiểu dữ liệu (Type Inference) mô tả vị trí và cách TypeScript xác định kiểu dữ liệu khi bạn không chú thích kiểu dữ liệu một cách rõ ràng .
Khi bạn khai báo một biến, bạn có thể sử dụng chú thích kiểu dữ liệu để chỉ định rõ ràng kiểu cho nó như đã được trình bày ở phần trên. Ví dụ:
let counter: number;
Tuy nhiên, nếu bạn khởi tạo giá trị cho biến counter
thành một số, TypeScript sẽ suy ra kiểu dữ liệu của biến counter
là number
. Ví dụ:
let counter = 0;
Nó tương đương với câu lệnh sau:
let counter: number = 0;
Tương tự như vậy, khi bạn gán một giá trị cho tham số của hàm, TypeScript sẽ suy ra kiểu dữ liệu của tham số thành kiểu dữ liệu của giá trị mặc định. Ví dụ:
function setCounter(max = 100) {
// ...
}
Trong ví dụ này, TypeScript suy ra kiểu dữ liệu của tham số max
là kiểu number
.
Tương tự, TypeScript suy ra kiểu dữ liệu trả về của hàm increment()
là kiểu number
:
function increment(counter: number) {
return counter++;
}
Nó giống như:
function increment(counter: number) : number {
return counter++;
}
Hãy xem xét đoạn mã sau:
let items = [1, 2, 3, null];
Để suy ra kiểu dữ liệu của biến items
, TypeScript cần xem xét kiểu của từng phần tử trong mảng.
Nó sử dụng thuật toán kiểu dữ liệu chung tốt nhất để phân tích kiểu dữ liệu của từng ứng viên và chọn kiểu dữ liệu tương thích với tất cả các ứng viên khác.
Trong trường hợp này, TypeScript chọn kiểu mảng số (number[]
) là kiểu dữ liệu phổ biến nhất.
Nếu bạn thêm một chuỗi vào mảng items
, TypeScript sẽ suy ra kiểu dữ liệu cho các phần tử là một mảng số và chuỗi:(number | string)[]
let items = [0, 1, null, 'Hi'];
Khi TypeScript không thể tìm thấy kiểu dữ liệu chung tốt nhất, nó sẽ trả về kiểu mảng liên hợp. Ví dụ:
let arr = [new Date(), new RegExp('\d+')];
Trong ví dụ này, TypeScript suy ra kiểu dữ liệu của arr
sẽ là (RegExp | Date)[]
.
TypeScript sử dụng vị trí của các biến để suy ra kiểu dữ liệu của chúng. Cơ chế này được gọi là kiểu dữ liệu theo ngữ cảnh. Ví dụ:
document.addEventListener('click', function (event) {
console.log(event.button); //
});
Trong ví dụ này, TypeScript biết rằng tham số event
là một thể hiện của MouseEvent
vì sự kiện click
.
Tuy nhiên, khi bạn thay đổi sự kiện click
thành sự kiện scroll
, TypeScript sẽ báo lỗi:
document.addEventListener('scroll', function (event) {
console.log(event.button); // compiler error
});
Lỗi:
Property 'button' does not exist on type 'Event'.(2339)
TypeScript biết rằng event
trong trường hợp này, là một thể hiện của UIEvent
, không phải của MouseEvent
. Và vì UIEvent
không có thuộc tính button
, do đó TypeScript sẽ báo lỗi.
Bạn sẽ tìm thấy kiểu dữ liệu theo ngữ cảnh trong các trường hợp có thể chẳng hạn như đối số cho lời gọi hàm, xác nhận kiểu, thành viên của đối tượng và mảng chuỗi, câu lệnh return và phía bên phải của phép gán.
Bảng sau cho thấy sự khác biệt giữa suy luận kiểu và chú thích kiểu:
Suy luận kiểu dữ liệu | Chú thích kiểu dữ liệu |
---|---|
TypeScript phải suy luận kiểu dữ liệu | Bạn cho TypeScript biết rõ kiểu dữ liệu |
Vì vậy, khi nào bạn sử dụng suy luận kiểu dữ liệu và chú thích kiểu dữ liệu?
Trong thực tế, bạn nên sử dụng suy luận kiểu dữ liệu càng nhiều càng tốt. Bạn chỉ nên sử dụng chú thích kiểu dữ liệu trong các trường hợp sau:
any
và bạn cần làm rõ giá trị.: [type]
để chỉ định rõ ràng kiểu dữ liệu cho một biến, hàm, giá trị trả về của hàm, v.v.Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Namespace được sử dụng để nhóm logic các chức năng. Namespace có thể bao gồm các interface, lớp, hàm và biến để hỗ trợ một nhóm các chức năng liên quan.
Trong hướng dẫn này bạn sẽ tìm hiểu về từ khóa readonly, static và cách sử dụng chúng trong TypeScript.
TypeScript có ba từ khóa kiểm soát quyền truy cập: public, private và protected để kiểm soát khả năng hiển thị của các thành phần dữ liệu của nó.
Định nghĩa một abstract class trong TypeScript bằng cách sử dụng từ khóa abstract. Abstract class chủ yếu được sử dụng để các lớp khác kế thừa từ chúng. Chúng ta không thể tạo một thể hiện của một abstract class.