TypeScript là gì?

Trong hướng dẫn này, bạn sẽ hiểu TypeScript là gì và những ưu điểm của nó so với JavaScript, cách cài đặt môi trường phát triển để làm việc với TypeScript và tạo ứng dụng Hello World đầu tiên bằng TypeScript.

Giới thiệu về TypeScript

TypeScript là một ngôn ngữ lập trình hướng đối tượng mã nguồn mở được phát triển và duy trì bởi Microsoft, được cấp phép theo giấy phép Apache 2. Nó là một tập hợp Javascript được định kiểu mạnh sẽ biên dịch thành JavaScript thuần túy.

TypeScript được phát triển dưới thời Anders Hejlsberg, người cũng là người dẫn đầu việc tạo ra ngôn ngữ lập trình C#. TypeScript được phát hành lần đầu tiên vào tháng 10 năm 2012.

TypeScript được xây dựng dựa trên JavaScript. Đầu tiên, bạn viết mã TypeScript. Sau đó, bạn biên dịch mã TypeScript thành mã JavaScript thuần túy bằng trình biên dịch TypeScript.

Khi bạn đã có mã JavaScript thuần túy, bạn có thể triển khai mã đó cho bất kỳ môi trường nào mà JavaScript chạy.

Tệp TypeScript sử dụng phần mở rộng .ts thay vì phần mở rộng .js của tệp JavaScript.

Trình biên dịch TypeScript thành JavaScript

TypeScript sử dụng các cú pháp JavaScript và thêm các cú pháp bổ sung để hỗ trợ kiểu dữ liệu.

Nếu bạn có một chương trình JavaScript không có bất kỳ lỗi cú pháp nào, nó cũng là một chương trình TypeScript. Nó có nghĩa là tất cả các chương trình JavaScript đều là chương trình TypeScript. Điều này rất hữu ích nếu bạn đang di chuyển cơ sở mã JavaScript hiện có sang TypeScript.

Sơ đồ sau cho thấy mối quan hệ giữa TypeScript và JavaScript:

Mối quan hệ giữa TypeScript và JavaScript

Tại sao nên sử dụng TypeScript

Các mục tiêu chính của TypeScript là:

  • Giới thiệu các kiểu dữ liệu cho JavaScript.
  • Triển khai các tính năng đã được lên kế hoạch của JavaScript trong tương lai hay còn gọi là ECMAScript Next hoặc ES Next cho JavaScript hiện tại.

Kiểu dữ liệu động trong JavaScript

JavaScript có kiểu dữ liệu động. Không giống như các ngôn ngữ được định kiểu dữ liệu tĩnh như Java hoặc C#. Ví dụ:

"Hello"

Bạn có thể biết rằng kiểu dữ liệu của nó là string. Ngoài ra, giá trị sau là kiểu số:

2020

Xem ví dụ sau:

let box;
box = "hello";
box = 100;

Kiểu dữ liệu của biến box thay đổi dựa trên giá trị được gán cho nó.

Để tìm kiểu dữ liệu của biến box khi thực thi, bạn sử dụng toán tử typeof:

let box;
console.log(typeof(box)); // undefined

box = "Hello";
console.log(typeof(box)); // string

box = 100;
console.log(typeof(box)); // number

Trong ví dụ này, câu lệnh đầu tiên xác định biến mà không gán giá trị. Kiểu dữ liệu của nó là undefined.

Sau đó, chúng tôi gán giá trị "Hello" cho biến box và hiển thị kiểu dữ liệu của nó. Kiểu dữ liệu của biến box bây giờ thay đổi thành string.

Cuối cùng, chúng tôi gán giá trị 100 cho biến box. Lần này, kiểu dữ liệu của biến box thay đổi thành number.

Như bạn có thể thấy, ngay sau khi giá trị được gán, kiểu dữ liệu của biến sẽ thay đổi.

Và bạn không cần phải chỉ định kiểu dữ liệu rõ ràng trong JavaScript. JavaScript sẽ tự động suy ra kiểu dữ liệu từ giá trị.

Kiểu dữ liệu động mang lại sự linh hoạt. Tuy nhiên, chúng cũng dẫn đến nhiều vấn đề.

Các vấn đề với kiểu dữ liệu động

Giả sử bạn có một hàm trả về một đối tượng product dựa trên một id:

function getProduct(id){
  return {
    id: id,
    name: `Awesome Gadget ${id}`,
    price: 99.5
  }
}

Phần sau sử dụng hàm getProduct() để truy xuất sản phẩm có id = 1 và hiển thị dữ liệu của nó:

const product = getProduct(1);
console.log(`The product ${product.Name} costs $${product.price}`);

Đây là kết quả đầu ra:

The product undefined costs $99.5

Nó không phải là những gì chúng tôi mong đợi.

Vấn đề với mã này là đối tượng product không có thuộc tính Name. Nó có thuộc tính name với chữ cái đầu tiên n viết thường.

Tuy nhiên, bạn chỉ có thể biết nó cho đến khi bạn chạy script.

Tham chiếu đến một thuộc tính không tồn tại trên đối tượng là một vấn đề phổ biến khi làm việc trong JavaScript.

Ví dụ sau định nghĩa một hàm mới log thông tin sản phẩm ra console:

const showProduct = (name, price)  => {
  console.log(`The product ${name} costs ${price}$.`);
};

Và sau đây sử dụng các hàm getProduct()showProduct():

const product = getProduct(1);
showProduct(product.price, product.name);

Đây là kết quả đầu ra:

The product 99.5 costs $Awesome Gadget 1

Lần này chúng ta truyền các đối số không đúng thứ tự vào hàm showProduct(). Đây là một vấn đề phổ biến khác mà bạn thường gặp phải khi làm việc với JavaScript.

Đây là lý do tại sao TypeScript ra đời.

Cách Typecript giải quyết các vấn đề của kiểu dữ liệu động

Để khắc phục sự cố tham chiếu thuộc tính không tồn tại trên một đối tượng, bạn thực hiện các bước sau:

Đầu tiên, định nghĩa “hình dạng” của đối tượng product bằng interface. Lưu ý rằng bạn sẽ tìm hiểu về interface trong hướng dẫn sau.

interface Product {
    id: number,
    name: string,
    price: number
};

Thứ hai, chỉ định rõ ràng Product làm kiểu dữ liệu trả về của hàm getProduct():

function getProduct(id) : Product {
  return {
    id: id,
    name: `Awesome Gadget ${id}`,
    price: 99.5
  }
}

Khi bạn tham chiếu một thuộc tính không tồn tại, trình chỉnh sửa mã sẽ thông báo cho bạn ngay lập tức:

const product = getProduct(1);
console.log(`The product ${product.Name} costs $${product.price}`);

Trình soạn thảo mã đã đánh dấu lỗi sau trên thuộc tính Name:

Trình soạn thảo mã đã đánh dấu lỗi sau trên thuộc tính Name trong TypeScript

Và khi di con trỏ chuột vào lỗi, bạn sẽ thấy một gợi ý giúp bạn giải quyết vấn đề:

Gợi ý giúp bạn giải quyết lỗi trong TypeScript

Để giải quyết vấn đề truyền các đối số không đúng thứ tự, bạn chỉ định rõ ràng các kiểu dữ liệu cho các tham số hàm:

const showProduct = (name: string, price:number)  => {
  console.log(`The product ${name} costs ${price}$.`);
};

Và khi bạn truyền các đối số sai kiểu dữ liệu cho hàm showProduct(), bạn sẽ nhận được lỗi:

const product = getProduct(1);
showProduct(product.price, product.name);

TypeScript cải thiện năng suất và giảm lỗi

TypeScript hỗ trợ kiểu dữ liệu làm tăng năng suất bằng cách giúp bạn tránh nhiều lỗi. Bằng cách sử dụng các kiểu dữ liệu, bạn có thể bắt lỗi tại thời điểm biên dịch thay vì để chúng xuất hiện trong thời gian chạy (runtime).

Hàm sau đây tính tổng hai số xy:

function add(x, y) {
   return x + y;
}

Nếu bạn lấy các giá trị từ các phần tử đầu vào HTML và chuyển chúng vào hàm, bạn có thể nhận được kết quả không mong muốn:

let result = add(input1.value, input2.value);
console.log(result); // result of concatenating strings

Ví dụ: nếu người dùng đã nhập 1020 thì hàm add() sẽ trả về 1020, thay vì 30.

Lý do là vì input1.valueinput2.value là chuỗi, không phải số. Khi bạn sử dụng toán tử + để thêm hai chuỗi, nó sẽ nối chúng thành một chuỗi duy nhất.

Khi bạn sử dụng TypeScript để chỉ định rõ ràng kiểu cho các tham số như sau:

function add(x: number, y: number) {
   return x + y;
}

Trong hàm này, chúng tôi đã thêm kiểu dữ liệu number vào các tham số. Hàm add() sẽ chỉ chấp nhận các tham số đầu vào có kiểu số, không chấp nhận bất kỳ giá trị nào khác.

Khi bạn gọi hàm như sau:

let result = add(input1.value, input2.value);

Trình biên dịch TypeScript sẽ gặp lỗi nếu bạn biên dịch mã TypeScript thành JavaScript. Do đó, bạn có thể ngăn lỗi xảy ra trong thời gian chạy (runtime).

TypeScript mang JavaScript của tương lai đến hiện tại

TypeScript hỗ trợ các tính năng sắp tới được lên kế hoạch trong ES Next cho các công cụ JavaScript hiện tại. Có nghĩa là bạn có thể sử dụng các tính năng JavaScript mới trước khi trình duyệt web (hoặc các môi trường khác) hỗ trợ đầy đủ chúng.

Hàng năm, TC39 phát hành một số tính năng mới cho ECMAScript, đây là tiêu chuẩn của JavaScript. Các đề xuất tính năng thường trải qua năm giai đoạn:

  • Giai đoạn 0: Người rơm
  • Giai đoạn 1: Đề xuất
  • Giai đoạn 2: Bản nháp
  • Giai đoạn 3: Ứng viên
  • Giai đoạn 4: Hoàn thành

Và TypeScript thường hỗ trợ các tính năng ở giai đoạn 3.

Thiết lập TypeScript

Các công cụ sau bạn cần thiết lập để bắt đầu với TypeScript:

  • Node.js - Node.js là môi trường mà bạn sẽ chạy trình biên dịch TypeScript. Lưu ý rằng bạn không cần biết Node.js.
  • Trình biên dịch TypeScript - một mô-đun Node.js biên dịch TypeScript thành JavaScript. Nếu bạn sử dụng JavaScript cho Node.js, bạn có thể cài đặt mô-đun ts-node. Nó là một trình thực thi TypeScript và REPL cho Node.js
  • Visual Studio Code hoặc VS Code - là một trình soạn thảo mã hỗ trợ TypeScript rất nổi tiếng được phát triển bởi Microsoft. VS Code rất được khuyến khích. Tuy nhiên, bạn có thể sử dụng trình soạn thảo yêu thích của mình.

Nếu bạn sử dụng VS Code, bạn có thể cài đặt phần mở rộng sau để tăng tốc quá trình phát triển:

  • Live Server - cho phép bạn khởi chạy Máy chủ cục bộ phát triển với tính năng tải lại nóng.

Cài đặt Node.js

Để cài đặt Node.js, bạn làm theo các bước sau:

  • Tới trang download Node.js.
  • Tải xuống phiên bản Node.js phù hợp với nền tảng của bạn, tức là Windows, macOS hoặc Linux.
  • Chạy gói cài đặt Node.js đã tải xuống hoặc tệp thực thi. Việc cài đặt khá đơn giản.
  • Xác minh cài đặt bằng cách mở terminal trên macOS và Linux hoặc dòng lệnh trên Windows và nhập lệnh node -v. Nếu bạn thấy phiên bản mà bạn đã tải xuống, thì bạn đã cài đặt thành công Node.js trên máy tính của mình.

Cài đặt trình biên dịch TypeScript

Để cài đặt trình biên dịch TypeScript, bạn khởi chạy Terminal trên macOS hoặc Linux và Command Prompt trên Windows và nhập lệnh sau:

npm install -g typescript

Sau khi cài đặt, bạn có thể nhập lệnh sau để kiểm tra phiên bản hiện tại của trình biên dịch TypeScript:

tsc --v

Nó sẽ trả về verison như thế này:

Version 4.0.2
Lưu ý rằng phiên bản của bạn sẽ mới hơn phiên bản này.

Nếu bạn đang sử dụng Windows và gặp lỗi sau:

'tsc' is not recognized as an internal or external command,
operable program or batch file.

Thì bạn nên thêm đường dẫn C:\Users\<user>\AppData\Roaming\npm vào biến PATH. Lưu ý rằng bạn nên thay đổi <user> thành tài khoản người dùng windows của mình.

Để cài đặt mô-đun ts-node toàn cục, bạn chạy lệnh sau từ Terminal trên macOS và Linux hoặc Command Prompt trên Windows:

npm install -g ts-node

Cài đặt Visual Studio Code

Để cài đặt Visual Studio Code, bạn làm theo các bước sau:

  • Điều hướng đến trang tải xuống Visual Studio Code.
  • Tải xuống phiên bản Visual Studio Code mới nhất phù hợp với hệ điều hành của bạn (Windows, macOS hoặc Linux)
  • Thực thi gói đã tải xuống hoặc file cài đặt để khởi chạy trình hướng dẫn cài đặt. Quá trình cài đặt cũng khá đơn giản.
  • Khởi chạy Visual Studio Code.

Bạn sẽ thấy Visual Studio Code như trong hình sau:

Visual Studio Code

Để cài đặt tiện ích mở rộng Live Server, bạn làm theo các bước sau:

Live Server
  • Nhấp vào tab Extensions để tìm các tiện ích mở rộng cho Visual Studio Code.
  • Nhập live server để tìm kiếm nó.
  • Nhấp vào install nút để cài đặt tiện ích.

“Hello, World!” bằng TypeScript

Tạo chương trình TypeScript Hello World trong Node.js

Đầu tiên, tạo một thư mục mới để lưu trữ mã, ví dụ helloword.

Tiếp theo, khởi chạy VS Code và mở thư mục đó.

Tạo một file TypeScript mới có tên là app.ts. Phần mở rộng của file TypeScript là .ts.

Nhập mã nguồn sau vào file app.ts:

let message: string = 'Hello, World!';
console.log(message);

Khởi chạy một Terminal mới trong VS Code bằng cách sử dụng phím tắt Ctrl+` hoặc truy cập menu Terminal > New Terminal

Gõ lệnh sau vào Terminal để biên dịch file app.ts:

tsc app.ts
Lệnh biên dịch file TypeScript

Nếu mọi thứ đều ổn, bạn sẽ thấy một file mới có tên là app.js được tạo bởi trình biên dịch TypeScript:

Kết quả sau khi biên dịch TypeScript

Để chạy file app.js trong node.js, bạn sử dụng lệnh sau:

node app.js

Nếu bạn đã cài đặt mô-đun ts-node, bạn chỉ cần sử dụng một lệnh duy nhất để biên dịch tệp TypeScript và thực thi tệp đầu ra cùng một lúc:

ts-node app.ts

Chạy chương trình TypeScript Hello World trong trình duyệt Web

Bạn làm theo các bước sau để tạo một trang web hiển thị thông báo Hello, World! trên trình duyệt web.

Đầu tiên, tạo một file mới có tên là index.html như sau:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TypeScript: Hello, World!</title>
</head>
<body>
    <script src="app.js"></script>
</body>
</html>

Sau đó thay đổi mã file app.ts như sau:

let message: string = 'Hello, World!';
// create a new heading 1 element
let heading = document.createElement('h1');
heading.textContent = message;
// add the heading the document
document.body.appendChild(heading);

Tiếp theo, biên dịch file app.ts:

tsc app.ts

Cuối cùng, mở Live Server từ VS Code bằng cách nhấp chuột phải vào index.html và chọn tùy chọn Open with Live Server:

Mở Live Server từ VS Code

Live Server sẽ mở file index.html như sau:

Live Server sẽ mở file index.html

Để thực hiện các thay đổi, bạn cần chỉnh sửa file app.ts. Ví dụ:

let message: string = 'Hello, TypeScript!';

let heading = document.createElement('h1');
heading.textContent = message;

document.body.appendChild(heading);

Và biên dịch file app.ts:

tsc app.ts

Trình biên dịch TypeScript sẽ tạo một file app.js mới và Live Server sẽ tự động tải lại tệp đó trên trình duyệt web.

Lưu ý rằng file app.js là file kết quả đầu ra của file app.ts, do đó bạn không bao giờ được trực tiếp thay đổi mã trong file này, nếu không bạn sẽ mất các thay đổi sau khi biên dịch lại file app.ts.

Trong hướng dẫn này, bạn đã tìm hiểu TypeScript là gì, vì sao nên sử dụng TypeScript, cách cài đặt môi trường phát triển để làm việc với TypeScript và tạo ứng dụng Hello World đầu tiên bằng TypeScript.

TypeScript
Bài Viết Liên Quan:
Namespace trong TypeScript
Trung Nguyen 14/10/2021
Namespace trong TypeScript

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.

Từ khóa readonly và static trong TypeScript
Trung Nguyen 13/10/2021
Từ khóa readonly và static trong TypeScript

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.

Từ khóa kiểm soát truy cập trong TypeScript
Trung Nguyen 12/10/2021
Từ khóa kiểm soát truy cập 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ó.

Abstract Class trong TypeScript
Trung Nguyen 11/10/2021
Abstract Class trong TypeScript

Đị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.