Các kiểu dữ liệu trong TypeScript
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.
Kiểu dữ liệu trong TypeScript là gì
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:
- Một kiểu dữ liệu là một nhãn mô tả các thuộc tính và phương thức khác nhau mà một giá trị có.
- Mỗi giá trị có một kiểu dữ liệu.
Các kiểu dữ liệu 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:
- Các kiểu dữ liệu nguyên thủy.
- Cáckiểu dữ liệu đối tượng.
Các kiểu dữ liệu nguyên thủy
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
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.

Mục đích của các kiểu dữ liệu trong TypeScript
Có hai mục đích chính của các kiểu dữ liệu trong TypeScript:
- Các kiểu dữ liệu được trình biên dịch TypeScript sử dụng để phân tích mã của bạn để tìm lỗi.
- Các kiểu dữ liệu cho phép bạn hiểu những giá trị nào được liên kết với các biến.
Ví dụ về 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ụ:

Type Annotation trong TypeScript
Type Annotation trong TypeScript là gì?
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.
Type Annotation cho biến và hằng số
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
.
Ví dụ về Type Annotation trong TypeScript
Type Annotation cho mảng
Để 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'];
Type Annotation cho đối tượng
Để 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
.
Type Annotation cho đối số hàm và kiểu trả về
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'.
Type Inference trong TypeScript
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 .
Suy luận kiểu dữ liệu cơ bản
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++;
}
Thuật toán kiểu dữ liệu chung tốt nhất
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)[]
.
Kiểu dữ liệu theo ngữ cảnh
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.
Suy luận kiểu dữ liệu vs Chú thích kiểu dữ liệu
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:
- Khi bạn khai báo một biến và gán giá trị cho nó sau đó.
- Khi bạn muốn chỉ định kiểu dữ liệu cho một biến không thể suy ra kiểu dữ liệu được.
- Khi một hàm trả về kiểu dữ liệu
any
và bạn cần làm rõ giá trị.
Tóm lược
- Mọi giá trị trong TypeScript đều có một kiểu dữ liệu.
- Kiểu dữ liệu là một nhãn mô tả các thuộc tính và phương thức mà một giá trị có.
- Trình biên dịch TypeScript sử dụng các kiểu dữ liệu để phân tích mã của bạn để tìm lỗi và lỗi.
- Sử dụng chú thích kiểu dữ liệu với cú pháp
: [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. - Suy luận kiểu dữ liệu xảy ra khi bạn khởi tạo biến, gán giá trị mặc định cho tham số và xác định kiểu dữ liệu trả về của hàm.
- TypeScript sử dụng thuật toán kiểu dữ liệu chung tốt nhất để chọn kiểu dữ liệu của ứng viên tốt nhất tương thích với tất cả kiểu dữ liệu của các biến.
- TypeScript cũng sử dụng kiểu dữ liệu theo ngữ cảnh để suy ra các kiểu dữ liệu của biến dựa trên vị trí của các biến.