thepcafe

TypeScript - Những kiểu dữ liệu cơ bản

Giới thiệu

Để lập trình một cách hiệu quả, chúng ta phải nắm rõ các kiểu dữ liệu cơ bản: numbers, strings, structures, boolean values, và like. Trong TypeScript hỗ trợ các kiểu dữ liệu tương tự như JavaScript.

HpBcaO_1559958960.jpeg

Boolean

Kiểu dữ liệu đơn giản nhất là cặp giá trị true/false, trong JavaScript và TypeScript gọi là giá trịboolean

let isDone: boolean = false;

Number

Như trong JavaScript, mọi số trong TypeScript đều là kiểu dữ liệu động. Nhữ số này chính là kiểu number. Ngoài việc hỗ trợ hexadecimal(hệ cơ số 16) và decimal literals(hệ cơ số 10), TypeScript cũng hỗ trợ kiểu binary(nhị phân) và octal literals(hệ cơ số 8) đã được giới thiệu trong ECMAScript 2015.

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;

String

Một trong những phần cơ bản khác để làm việc và lập trình trong JavaScript cho tạo trang web cũng như servers là làm việc với dữ liệu kiểu văn bản. Giống như các ngôn ngữ lập trình khác, chúng ta sử dụng kiểu string để nói đến kiểu dữ liệu văn bản. Như JavaScript thì TypeScript cũng sử dụng dấy nháy kép (") hoặc dấu nháy đơn (') bao quanh chuỗi.

let color: string = "blue";
color = 'red';

Bạn cũng có thể sử dụng template strings, nó có thể xuống dòng và nhúng được các biểu thức(expressions) vào nội dung. Chuỗi được bao bởi ký tự backtick/backquote (`), và nhúng biểu thức dưới dạng ${ expr }.

let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ fullName }.

I'll be ${ age + 1 } years old next month.`;

Đoạn trên tương đương với khai báo sau:

let sentence: string = "Hello, my name is " + fullName + ".\n\n" +
    "I'll be " + (age + 1) + " years old next month.";

Array

TypeScript, giống JavaScript, cho phép bạn làm việc với mảng dữ liệu. Kiểu mảng có thể được khai báo theo một trong hai cách. Kiểu đầu tiên bạn sử dụng khai báo với kiểu dữ liệu theo sau là dấu[] để khai báo là một mảng chứa các thành phần có kiểu dữ liệu đã được khai báo:

let list: number[] = [1, 2, 3];

Cách thứ hai là khai báo kiểu Array<elemType>:

let list: Array<number> = [1, 2, 3];

Tuple

Kiểu Tuple cho phép bạn khai báo một mảng với số lượng các thành phần có kiểu xác định nhưng không nhất thiết là phải cùng một kiểu. Ví dụ, bạn muốn thể hiện một cặp dữ liệu với kiểu string vànumber:

// Khai báo dữ liệu kiểu tuple
let x: [string, number];
// Khởi tạo
x = ["hello", 10]; // OK
// Khởi tạo sai
x = [10, "hello"]; // Error

Khi truy cập một thành phần mà biết trước vị trí, theo index, ta sẽ nhận được giá trị có kiểu dữ liệu của nó:

console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'

Khi truy cập đến thành phần ngoài tập khai báo kiểu dữ liệu từ trước, kiểu dữ liệu union sẽ được sử dụng thay thế:

x[3] = "world"; // OK, 'string' can be assigned to 'string | number'

console.log(x[5].toString()); // OK, 'string' and 'number' both have 'toString'

x[6] = true; // Error, 'boolean' isn't 'string | number'

Kiểu dữ liệu Union là phần nâng cao sẽ được giới thiệu trong bài viết sau.

Enum

Thêm một kiểu dữ liệu có trong chuẩn của JavaScript chính là enum. Giống như trong ngôn ngữ C#, kiểu enum là một cách khai báo tập các giá trị số với một cái tên rất chi là thân thiện :)

enum Color {Red, Green, Blue}
let c: Color = Color.Green;

Mặc định, enums bắt đầu tập giá trị của mình ở chỉ số 0. Bạn có thể thay đổi điều này bằng cách đặt lại giá trị của nó bằng 1. Ví dụ, chúng ta có thể bắt đầu tập giá trị trong ví dụ trước là 1 thay vì 0:

enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

Hoặc thậm chí là bạn có thể đặt mọi giá trị trong tập của enum:

enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

Một tính năng tiện dụng của enums là bạn có thể sử dụng giá trị số hoặc tên của giá trị đó. Ví dụ:

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];

alert(colorName);

Any

Chúng ta cần phải khai báo, miêu tả giá trị của một biến khi viết ứng dụng. Những giá trị đó có thể đến từ một nội dung động, ví dụ từ thư viện của một bên thứ 3. Trong những trường hợp đó, chúng ta muốn bỏ qua việc kiểm tra kiểu dữ liệu khi biên dịch. Để làm được điều này, chúng ta thêm kiểu any :

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

Kiểu any là một cách rất tốt để làm việc với JavaScript có sẵn, cho phép bạn khai báo kiểm tra hay không kiểm tra kiểu dữ liệu trong quá trình biên dịch. Bạn có thể dùng dữ liệu kiểu Object trong khai báo này. Nhưng những biến kiểu Object chỉ cho phép bạn gán giá trị cho chúng - không cho phép bạn gọi các phương thức trên các biến này, mặc dù các phương thức đã được khai báo:

let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)

let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

Kiểu any cũng rất hữu dụng khi bạn biết kiểu của một phần dữ liệu. Ví dụ, bạn có một mảng dữ liệu với các kiểu khác nhau:

let list: any[] = [1, true, "free"];

list[1] = 100;

Void

void có một chút đối ngược với any: Tất cả các thành phần đều không có kiểu dữ liệu nào cả. Bạn có thể thường bắt gặp trong kiểu dữ liệu trả về của hàm:

function warnUser(): void {
    alert("This is my warning message");
}

Khai báo biến kiểu void không hữu dụng bởi vì bạn chỉ có thể gán biến kiểu undefined và null:

let unusable: void = undefined;

Null và Undefined

Trong TypeScript, cả undefined và null thực sự có kiểu riêng của nó là undefined và null. Giống như void, chúng không thự sự hữu dụng khi khai báo:

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

Mặc định undefined và null là kiểu con của các kiểu khác. Nghĩa là bạn có thể gán giá trịundefined và nullcho kiểu number.

Tuy nhiên, sử dụng cờ --strictNullChecks , null và undefined chỉ có thể gán cho void và kiểu của chúng. Điều này giúp tránh cho rất nhiều lỗi hay gặp. Trong trường hợp bạn muốn gán kiểu string hoặc null hoặc undefined, bạn có thể sử dụng kiểu union string | null | undefined.


Chú thích: việc sử dụng --strictNullChecks được khuyến khích khi có thể.

Never

Kiểu never thể hiện kiểu dữ liệu không bao giờ xảy ra. never trả về kiểu dữ liệu của hàm biểu thức(function expression) hoặc arrow function expression, chúng luôn ném ra ngoại lệ hoặc không có giá trị trả về; Các biến cũng có kiểu never khi chúng không bao giờ được sử dụng.

Một vài ví dụ hàm trả về never:

// Function returning never must have unreachable end point
function error(message: string): never {
    throw new Error(message);
}

// Inferred return type is never
function fail() {
    return error("Something failed");
}

// Function returning never must have unreachable end point
function infiniteLoop(): never {
    while (true) {
    }
}

Type assertions(khẳng định kiểu)

Đôi khi bạn muốn giá trị có kiểu cụ thể nào đó được khai báo trong TypeScript mà bạn chắc chắn nó đúng. Type assertions là một cách để thông báo với trình biên dịch rằng “tin tao đi :D, Tao biết là tao đang làm gì.” Type assertion giống như ép kiểu trong các ngôn ngữ khác, những không thực thi kiểm tra dữ liệu theo kiểu đặc biệt nào đó và cũng không tái cấu trúc lại dữ liệu. Nó không mất thời gian biên dịch, trình biên dịch sử dụng trực tiếp luôn giá trị được khai báo. Type assertions có hai kiểu. Đầu tiên là cú pháp “angle-bracket”:

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

Và thứ hai là cú pháp as:

let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

Khi sử dụng TypeScript với JSX, chỉ có kiểu asmới được cho phép.

Chú thích về let

Có thể bạn thấy nhiều chú thích về sử dụng let thay cho var trong JavaScript. Từ khoá let là cấu trúc mới của JavaScript mà TypeScript làm cho nó phổ biến. Nhiều lỗi phổ thông trong JavaScript được giảm bớt bằng cách sử dụng let, các bạn nên sử dụng thay thế cho var bất kỳ lúc nào có thể.