Typescript là gì? Ưu và nhược điểm của Typescript

2182

Typescript là gì? Hôm nay chúng ta sẽ cùng nhau phân tích cặn kẽ điểm mạnh và điểm yếu của typescript để có thể quyết định xem nên sử dụng nó như thế nào cho hiệu quả nhé!

Định nghĩa Typescript là gì?

Typescript là gì

TypeScript là gì? – Là một ngôn ngữ được Microsoft tặng free cho chúng ta, nền tảng của TypeScript ít nhiều cũng có sự liên quan đến JavaScript vì nó là một ngôn ngữ mã nguồn mở của JavaScript. Vai trò của TypeScript là dùng để thiết kế và xây dựng các dự án ứng dụng quy mô lớn mang tính chất phức tạp.

Khác với sự đơn giản của JavaScript, du TypeScript cũng đồng thời kế thừa nhiều định nghĩa, khái niệm của đa dạng các ngôn ngữ C#, Java,… nhưng TypeScript lại có yêu cầu cao về trật tự rõ ràng. 

TypeScript được xem là một phiên bản nâng cao hơn của JavaScript vì nó được thiết kế thêm nhiều chức năng tiện lợi hơn, cải tiến hơn từ những điểm yếu của JavaScript như các lớp hướng đối tượng và Static Structural typing, bên cạnh đó TypeScript còn có thể hoạt động rộng rãi cho các ứng dụng của ngôn ngữ Angular2 và Nodejs.

  Kiểu enum trong TypeScript: làm việc như thế nào, sử dụng ra sao
  Học TypeScript trong 30 phút

Chức năng của TypeScript là gì?

Static Typing

Một trong những chức năng không thể lẫn vào đâu được của TypeScript đó là hỗ trợ ‘static typing’. Đồng nghĩa với việc bạn có thể khai báo kiểu cho biến, và trình biên dịch sẽ giảm được tỷ lệ gán sai kiểu của các giá trị. Nếu khai báo kiểu bị bỏ qua, chúng sẽ được tự động phát hiện từ code của bạn.

Ví dụ: Các biến, tham số của hàm hoặc giá trị trả lại có thể có các kiểu được định nghĩa khi khởi tạo:

var burger: string = 'Spaghetti',     // String 
    calories: number = 400,           // Numeric
    tasty: boolean = true;            // Boolean

// Alternatively, you can omit the type declaration:
// var pasta = 'Spaghetti';

// The function expects a string and an integer.
// It doesn't return anything so the type of the function itself is void.

function speak(food: string, energy: number): void {
  console.log("Our " + food + " has " + energy + " calories.");
}

speak(pasta, calories);

Toàn bộ khai báo kiểu sẽ bị xóa trong trường hợp TypeScript biên dịch thành JavaScript thành công

// JavaScript code from the above TS example.

var burger = 'Spaghetti',
    calories = 400, 
    tasty = true; 

function speak(food, energy) {
    console.log("Our " + food + " has " + energy + " calories.");
}

speak(Spaghetti, calories);

Biên dịch tsc sẽ báo lỗi khi chúng ta thao tác không hợp lệ. Ví dụ:

// The given type is boolean, the provided value is a string.
var tasty: boolean = "I haven't tasted it yet";
main.ts(1,5): error TS2322: Type 'string' is not assignable to type 'boolean'.

Hệ thống cũng sẽ báo lỗi nếu thao tác truyền sai tham số tới một hàm:

function speak(food: string, energy: number): void{
  console.log("Our " + food + " has " + energy + " calories.");
}

// Arguments don't match the function parameters.
speak("Sea Food Spaghetti", "a ton of");
main.ts(5,30): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Các kiểu dữ liệu được sử dụng phổ biến nhất:

  • Any – Một biến với kiểu này có thể có giá trị là một string, number hoặc bất kỳ kiểu nào.
  • String – Giống chức năng của string trong JavaScript, có thể được bao quanh bởi ‘dấu nháy đơn’ hoặc “dấu nháy kép”.
  • Number – Tất cả giá trị số trong hàm đều được biểu diễn bởi kiểu number, không có định nghĩa riêng cho số nguyên (interger), số thực (float) cũng như các kiểu khác.
  • Boolean – true hoặc false, sử dụng 0 và 1 sẽ gây ra lỗi biên dịch.
  • Arrays – Có 2 kiểu cú pháp: my_arr: number[]; hoặc my_arr: Array<number>.
  • Void – sử dụng khi hàm không trả lại bất kỳ giá trị nào.

Để xem danh sách tất cả các kiểu biến, đọc tài liệu hướng dẫn của TypeScript tại đây.

Interfaces

Chức năng chính của Interfaces là sử dụng để kiểm tra, xem một đối tượng có phù hợp với một cấu trúc nhất định hay không, trợ giúp trong giai đoạn giai đoạn phát triển.

Bằng cách định nghĩa một interface, ta có thể đặt tên trong trường hợp có sự kết hợp đặc biệt của các biến, đảm bảo rằng chúng luôn luôn đi cùng nhau.

Ví dụ:

// Here we define our Food interface, its properties, and their types.
interface Food {
    name: string;
    calories: number;
}

// We tell our function to expect an object that fulfills the Food interface. 
// This way we know that the properties we need will always be available.
function speak(food: Food): void{
  console.log("Our " + food.name + " has " + food.calories + " calories.");
}

// We define an object that has all of the properties the Food interface expects.
// Notice that types will be inferred automatically.
var ice_cream = {
  name: "cookies", 
  calories: 250
}

speak();

Ngoài ra bạn nên biết rằng, thứ tự của các thuộc tính không quan trọng bằng việc chúng ta phải fill đủ số lượng các thuộc tính và đúng kiểu. Nếu một thuộc tính nào đó bị thiếu, hoặc sai kiểu, hoặc sai tên, trình biên dịch sẽ cảnh báo chúng ta.

interface Food {
    name: string;
    calories: number;
}

function speak(food: Food): void{
  console.log("Our " + food.name + " has " + food.calories + " grams.");
}

// We've made a deliberate mistake and name is misspelled as nmae.
var cookies = {
  nmae: "cookies", 
  calories: 250
}

speak(cookies);
main.ts(16,7): error TS2345: Argument of type '{ nmae: string; calories: number; } 
is not assignable to parameter of type 'Food'. 
Property 'name' is missing in type '{ nmae: string; calories: number; }'.

Classes

Trong các dự án, ứng dụng lớn, lập trình hướng đối tượng rất hay được các Dev sử dụng nhất là trong các ngôn ngữ như Java hoặc C#.

TypeScript cung cấp hệ thống class khá tương đồng với các ngôn ngữ này ví dụ như chức năng kế thừa, abstract classes, interface implementations, setter/getters, …

Từ phiên bản ECMAScript 2015 trở đi, classes được xem là một tính năng có sẵn trong JS và có thể không cần sử dụng TypeScript. Mặc dù 2 phiên bản này có nhiều chức năng tương tự nhau, nhưng chúng vẫn có điểm khác biệt, đó là TypeScript nghiêm ngặt hơn.

Ví dụ:

class Menu {
  // Our properties:
  // By default they are public, but can also be private or protected.
  items: Array<string>;  // The items in the menu, an array of strings.
  pages: number;         // How many pages will the menu be, a number.

  // A straightforward constructor. 
  constructor(item_list: Array<string>, total_pages: number) {
    // The this keyword is mandatory.
    this.items = item_list;    
    this.pages = total_pages;
  }

  // Methods
  list(): void {
    console.log("Our special meal today is:");
    for(var i=0; i<this.items.length; i++) {
      console.log(this.items[i]);
    }
  }

} 

// Create a new instance of the Menu class.
var sundayMenu = new Menu(["Banana cakes","waffles","Lemon juice"], 1);

// Call the list method.
sundayMenu.list();

Cú pháp này khá quen thuộc cho dân Java hoặc C#. Tương tự cho kế thừa:

class HappyMeal extends Menu {
  // Properties are inherited

  // A new constructor has to be defined.
  constructor(item_list: Array<string>, total_pages: number) {
    // In this case we want the exact same constructor as the parent class (Menu), 
    // To automatically copy it we can call super() - a reference to the parent's constructor.
    super(item_list, total_pages);
  }

  // Just like the properties, methods are inherited from the parent.
  // However, we want to override the list() function so we redefine it.
  list(): void{
    console.log("Our special menu for children:");
    for(var i=0; i<this.items.length; i++) {
      console.log(this.items[i]);
    }

  }
}

// Create a new instance of the HappyMeal class.
var menu_for_children = new HappyMeal(["French Fries","Coke","toy"], 1);

// This time the log message will begin with the special introduction.
menu_for_children.list();

Modules

Tính module hóa rất quan trọng khi bạn đang thực hiện những dự án lớn. Nó phân chia code thành nhiều thành phần nhỏ và còn có khả năng tái sử dụng giúp dự án của bạn dễ tổ chức và dễ hiểu hơn so với file có hàng ngàn dòng code.

TypeScript có chức năng exporting và importing các module, nhưng bản thân nó không thể xử lý thực sự việc liên kết giữa các file. Dùng require.js cho các ứng dụng client và CommonJS cho Node.js để cho phép modules TS dựa trên các thư viện của bên thứ ba.

Đặt trường hợp có 2 file: 1 file export một hàm, 1 file import, chúng ta sẽ gọi nó là:

exporter.ts

var sayHi = function(): void {
    console.log("Hello!");
}

export = sayHi;

importer.ts

import sayHi = require('./exporter');
sayHi();

Để có thể hoàn thành thao tác, cần download require.js và thêm nó trong một thẻ script – xem hướng dẫn typescript là gì của requirejs.org. Sau đó biên dịch 2 file .ts. Mộ tham số mở rộng cần được thêm vào để nói với TypeScript chúng ta đang xây dựng các module cho require.js (còn được gọi là AMD):

tsc --module amd *.ts

Generics

Chức năng của Generics là cho phép cùng một hàm có thể chấp nhận các tham số với nhiều kiểu khác nhau. Việc tạo ra các thành phần có thể tái sử dụng với generics tốt hơn sử dụng kiểu any, vì generics bảo tồn kiểu của các biến vào và ra của chúng.

Ví dụ: Generics trong ví dụ dưới đây đã nhận một tham số và trả lại một mảng chứa cùng tham số

// The <T> after the function name symbolizes that it's a generic function.
// When we call the function, every instance of T will be replaced with the actual provided type.

// Receives one argument of type T,
// Returns an array of type T.

function genericFunc<T>(argument: T): T[] {    
  var arrayOfT: T[] = [];    // Create empty array of type T.
  arrayOfT.push(argument);   // Push, now arrayOfT = [argument].
  return arrayOfT;
}

var arrayFromString = genericFunc<string>("beep");
console.log(arrayFromString[0]);         // "beep"
console.log(typeof arrayFromString[0])   // String

var arrayFromNumber = genericFunc(42);
console.log(arrayFromNumber[0]);         // 42
console.log(typeof arrayFromNumber[0])   // number

Lần đầu tiên gọi hàm chúng ta thiết lập kiểu thành string. Điều này không bắt buộc vì trình biên dịch có thể xem tham số được truyền và tự động quyết định kiểu nào phù hợp nhất, giống như lần gọi hàm thứ 2.

Mặc dù không bắt buộc, luôn luôn cung cấp kiểu được coi là cần thiết vì trình biên dịch có thể đoán sai kiểu trong các kịch bản phức tạp.

Tài liệu hướng dẫn của TypeScript là gì gồm một vài ví dụ cao cấp bao gồm generics classes, kết hợp chúng với interfaces, …ở typescriptlang.org.

Ưu điểm của Typescript là gì?

Typescript là gì

TypeScript thật sự thuận tiện và hoàn toàn miễn phí

Đối với loại ngôn ngữ lập trình tĩnh như TypeScript, tất cả những số liệu, thông số của bạn sẽ dễ dàng được lấy hơn nhờ IDE và trình biên dịch.

TypeScript hỗ trợ quá trình tìm kiếm giúp bạn tiết kiệm thời gian kiểm tra lại code, không cần thông qua bất cứ một ai để có thể tìm thông tin dữ liệu, ngoài ra TypeScript làm giảm phần trăm va chạm lỗi trong thời gian vận hành.

Ngoài ra, đây cũng là một trong những phần mềm nổi trội được Microsoft hỗ trợ hoàn toàn miễn phí.

  TypeScript thoáng qua
  So sánh Typescript với JavaScript

Thao tác nhanh chóng và đơn giản hơn

Ngôn ngữ TypeScript có thao tác khá đơn giản, tiết kiệm thời gian hơn nhưng lại đem đến kết quả tốt đến bất ngờ, nó khắc phục tình trạng xuất hiện lỗi và dễ đọc hơn.

Cụ thể là, đối với ngôn ngữ thông thường người dùng thường thao tác theo các bước như:

  • Restart lại hàm, tạo đối số, hoàn thành đoạn mã
  • Sau khi apply hết các đoạn mã, công cụ cần thiết thì cho vận hành
  • Trong quá trình vận hành nếu phát hiện lỗi thì sửa chữa lại.

Tái cấu trúc

Chắc chắn trong quá trình viết code, các lập trình viên sẽ thường xuyên mắc phải nhiều lỗi nhỏ và cần chỉnh sửa, việc sử dụng TypeScript sẽ giúp bước chỉnh sửa code trở nên dễ dàng hơn nhờ hiệu quả của lệnh Rename Symbol/Find All Occurrences.

Đối với các ngôn ngữ khác, khi muốn sửa chi tiết nào đó thì thường phải thay đổi luôn những tập tin khác nếu có liên quan hoặc sử dụng RegEx

Trong trường hợp người dùng TypeScript muốn nâng cấp hệ thống của mình (thêm hoặc xóa thuộc tính, đổi tên,…) thì TypeScript sẽ giúp bạn tái cấu trúc lại sao cho phù hợp với nhu cầu tìm kiếm của bạn mà không gây náo loạn trong hệ thống. Trong trường hợp code của bạn không match được bất cứ dữ liệu nào thì sẽ được báo đến bạn ngay để được xử lý ổn thỏa.

Giảm tỷ lệ mắc lỗi trong hệ thống

Nhờ vào việc cảnh báo lỗi ngay khi viết code, nên tỷ lệ mắc lỗi trong hệ thống khi sử dụng TypeScript khá thấp, TypeScript sẽ trả lại giá trị null hoặc gợi ý thay đổi chỉnh sửa. Mỗi lần chỉnh sửa sau khi được TypeScript báo lỗi thì phần trăm hệ thống hoạt động mà không mắc phải lỗi là rất cao, có thể dễ dàng thấy được TypeScript giúp người dùng tiết kiệm không ít thời gian để sửa lỗi.

  12 Thư viện JavaScript trực quan hoá dữ liệu hot nhất năm 2019

Hạn chế thử nghiệm Boilerplate

Với quy trình kiểm tra và báo lỗi tự động ngay khi code, khi bạn đã chắc chắn rằng các biến dữ liệu của mình nằm ở đúng chỗ thì bạn không cần phải lo hệ thống không vận hành hoặc không cần phải kiểm tra lại nữa.

Điều này sẽ giúp bạn tiết kiệm thời gian, không đặt quá nhiều chú ý vào những thao tác đơn giản cho việc kiểm tra mà có thể tận dụng thời gian tối ưu hơn bằng cách kiểm tra chất lượng logic của hệ thống.

Việc hạn chế được các bước thử nghiệm sẽ giúp tiết kiệm được thời gian hơn, nâng cao hiệu quả công việc của các lập trình viên.

Hợp nhất mã đơn giản

Sau khi hoàn thiện được một đoạn code và cho chúng chạy thử nghiệm, có thể ngay trong môi trường đó mọi thứ đều hoạt động trơn tru, nhưng bạn có chắc được đoạn code đó cũng sẽ hoạt động tốt khi ở trong môi trường điều kiện khác? 

Một trong những điểm mạnh của TypeScript là bạn có thể hợp nhất mã một cách đơn giản để có thể dễ dàng kiểm tra đánh giá đoạn mã bạn vừa mới cho ra đời kia bằng cách sử dụng Typedef – kiểm tra biên dịch.

Lại một lần nữa, TypeScript lại giúp người dùng tiết kiệm thời gian và công sức!

  Khi nào thì sử dụng Generics trong TypeScript
  freeCodeCamp là gì? Các giáo trình chứng chỉ IT dành cho lập trình viên

Hỗ trợ tối ưu hóa quy trình làm việc

TypeScript sẽ không khuyến khích người dùng nhảy bước, thực hiện sai thao tác. TypeScript khuyến khích người dùng đưa ra quyết định về kiểu dữ liệu khi sử dụng ngôn ngữ kiểu tĩnh trước khi thực hiện thao tác, các bước tiếp theo. Chính vì những quy luật như thế sẽ giúp cho các lập trình viên tối ưu được quy trình làm việc hiệu quả hơn.

Nhược điểm của Typescript là gì?

Bất kỳ ngôn ngữ nào cũng có điểm yếu và hạn chế của nó, và TypeScript cũng vậy, điểm hạn chế của TypeScript là:

Bắt buộc dùng biên dịch

Để có thể vận hành một tệp TypeScript với đuôi .js trên nền tảng Node.js bạn bắt buộc phải dùng trình biên dịch để có thể sử dụng.

Bước thiết lập cồng kềnh 

Trước khi có thể sử dụng được TypeScript, bạn cần đảm bảo rằng máy chủ Node.js, trình thử nghiệm và webpack đều có thể hoạt động với TypeScript, nếu không thì bạn sẽ không sử dụng được.

Bên cạnh đó, mỗi khi bạn apply thêm bất kỳ library nào như Redux, React và Styled-Component thì bạn cũng phải thêm Typedef vào.

Chỉ là phần ngôn ngữ mở rộng hỗ trợ

Sau cùng, chức năng của TypeScript cũng chỉ là để biên dịch về JavaScript, nó không phải là một ngôn ngữ có thể vận hành độc lập và nó cũng đồng thời không thể thay thế được vai trò của JavaScript. Chức năng của TypeScript bị giới hạn bởi chức năng của JavaScript, TypeScript chỉ là được nâng cấp từ điểm yếu của JavaScript.

Chỉ với mỗi TypeScript, người dùng không thể nào hoàn thiện được các công đoạn của dự án, công dụng của TypeScript chỉ thực sự nổi bật khi được kết hợp nhuần nhuyễn và tối ưu với các ngôn ngữ, nền tảng và tool khác.

TypeScript có thực sự là một mã nguồn mở?

Có nhiều luồng ý kiến cho rằng TypeScript là một mã nguồn mở, và đó cũng là một trong những lý do họ thích sử dụng TypeScript. Nhưng liệu đó có phải sự thật?

Đúng! TypeScript thực sự là một mã nguồn mở nhưng nó vẫn nằm dưới sự chi phối của Microsoft – công ty phần mềm nổi tiếng về các phiên bản phần mềm độc quyền. 

Nhiều người dự đoán, TypeScript là một sản phẩm marketing của Microsoft dùng để thu hút người dùng về công năng và sự miễn phí. Tuy nhiên sau cùng, việc Microsoft có kéo dài việc miễn phí này hay không vẫn phụ thuộc rất nhiều vào Microsoft và người dùng hoàn toàn bị động trong chuyện này.

tuyển dụng it

Cài đặt TypeScript

Cách dễ nhât để thiết lập TypeScript là thông qua trình quản lý NPM (Node.js).

Các bạn có thể dễ dàng thao tác và sử dụng thử các lệnh cơ bản, đơn giản sau đây dưới để có thể cài đặt TypeScript package toàn cục:

npm install -g typescriptjavascript:void(0)

Open bât kỳ cửa sổ terminal ở bất kỳ đâu và chạy lệnh tsc -vnếu cài đặt thành công màn hình sẽ như thế này:

tsc -v
Version 1.8.10

topdev

Hướng dẫn biên dịch sang từ TypeScript sang JavaScript

TypeScript được viết trong các file .ts (hoặc .tsx cho JSX), nó không thể sử dụng trực tiếp trong trình duyệt và cần biên dịch thành JavaScript. Điều này có thể thực hiện với một số cách:

  • Sử dụng các task runner như Gulp
  • Trực tiếp trong Visual Studio hoặc các IDE và trình soạn thảo khác
  • Trong terminal sử dụng lệnh tsc

Đối với Newbie chúng nên bắt đầu từ cách dễ nhất:

Câu lệnh sau sẽ nhận một file TypeScipt là main.ts và chuyển nó thành JavaScipt main.js. Nếu main.js đã tồn tại nó sẽ bị ghi đè:

tsc main.ts

Trong cùng 1 thời điểm, chúng ta có thể biên dịch nhiều file bằng cách liệt kê chúng hoặc áp dụng các wildcard:

# Will result in separate .js files: main.js worker.js.
tsc main.ts worker.ts    

# Compiles all .ts files in the current folder. Does NOT work recursively.
tsc *.ts

Chúng ta cũng có thể sử dụng tùy chọn –watch để tự động biên dịch một file TypeScript khi có thay đổi:

# Initializes a watcher process that will keep main.js up to date.
tsc main.ts --watch

Một file tsconfig.json chứa nhiều thiết lập đôi khi cũng được viết bởi các TypeScript giàu kinh nghiệm. Các file như thế rất tiện lợi khi làm việc trên các dự án lớn có nhiều file .ts, nó hỗ trợ tự động hóa một phần tiến trình.

Để hiểu thêm về tsconfig.json, bạn có thể tham khảo thêm các tài liệu hướng dẫn TypeScript là gì của typescriptlang.org

TopDev tổng hợp

Có thể bạn muốn xem thêm:

Xem thêm nhiều việc làm liên quan đến TypeScript hấp dẫn tại TopDev!

Báo cáo bài viết vi phạm bản quyền>>