Bộ câu hỏi phỏng vấn Typescript phần 1

TypeScript là gì?


TypeScript là một dự án mã nguồn mở được phát triển bởi Microsoft, nó có thể được coi là một phiên bản nâng cao của Javascript bởi việc bổ sung tùy chọn kiểu tĩnh và lớp hướng đối tượng mà điều này không có ở Javascript. TypeScript có thể sử dụng để phát triển các ứng dụng chạy ở client-side (Angular2) và server-side (NodeJS).

TypeScript là gì

TypeScript sử dụng tất cả các tính năng của của ECMAScript 2015 (ES6) như classes, modules. Không dừng lại ở đó nếu như ECMAScript 2017 ra đời thì mình tin chắc rằng TypeScript cũng sẽ nâng cấp phiên bản của mình lên để sử dụng mọi kỹ thuật mới nhất từ ECMAScript. Thực ra TypeScript không phải ra đời đầu tiên mà trước đây cũng có một số thư viện như CoffeScriptDart được phát triển bởi Google, tuy nhiên điểm yếu là hai thư viện này sư dụng cú pháp mới hoàn toàn, điều này khác hoàn toàn với TypeScript, vì vậy tuy ra đời sau nhưng TypeScript vẫn đang nhận được sự đón nhận từ các lập trình viên.

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


  • Dễ phát triển dự án lớn: Với việc sử dụng các kỹ thuật mới nhất và lập trình hướng đối tượng nên TypeScript giúp chúng ta phát triển các dự án lớn một cách dễ dàng.
  • Nhiều Framework lựa chọn: Hiện nay các Javascript Framework đã dần khuyến khích nên sử dụng TypeScript để phát triển, ví dụ như AngularJS 2.0 và Ionic 2.0.
  • Hô trợ các tính năng của Javascript phiên bản mới nhất: TypeScript luôn đảm bảo việc sử dụng đầy đủ các kỹ thuật mới nhất của Javascript, ví dụ như version hiện tại là ECMAScript 2015 (ES6).
  • Là mã nguồn mở: TypeScript là một mã nguồn mở nên bạn hoàn toàn có thể sử dụng mà không mất phí, bên cạnh đó còn được cộng đồng hỗ trợ.
  • TypeScript là Javscript: Bản chất của TypeScript là biên dịch tạo ra các đoạn mã javascript nên ban có thê chạy bất kì ở đâu miễn ở đó có hỗ trợ biên dịch Javascript. Ngoài ra bạn có thể sử dụng trộn lẫn cú pháp của Javascript vào bên trong TypeScript, điều này giúp các lập trình viên tiếp cận TypeScript dễ dàng hơn.

Các kiểu dữ liệu trong Typescript là gì?


Mỗi biến (variable) có một kiểu cố định liên kết với nó. Kiểu của biến được kiểm tra lúc compiled-time và trình biên dịch yêu cầu ta phải khai báo rõ kiểu của biến trước khi sử dụng.

Sau đây là danh sách các kiểu dữ liệu trong TypeScript.

Kiểu Boolean

Kiểu boolean có hai giá trị là true hoặc false và cả Javascript lẫn TypeScript đều gọi là boolean.

TypeScript:

let isDone: boolean = false;

Kết quả Javascript:

var isDone = false;

Kiểu Number

Cũng tương tự như trong Javascript thì trong TypeScript chỉ tồn tại một kiểu Number, còn việc phân chia các kiểu nhỏ hơn như số nguyên, só thực sẽ phụ thuộc vào giá trị mà bạn gán cho nó. TypeScript cũng hỗ trợ kiểu nhị phân và bát phân được giới thiệu trong ECMAScript 2015.

TypeScript:

var decimal: number = 12;
var hex: number = 0xf00d;
var binary: number = 0b1010;
var octal: number = 0o744;

Kết quả Javascript:

var decimal = 12;
var hex = 0xf00d;
var binary = 10;
var octal = 484;

Kiểu String

Kiểu string đơn giản là một chuỗi (một đoạn text) được bao bọc bởi cặp ký tự ' hoặc ".

TypeScript:

let username: string = "thehalfheart";

Kết quả Javascript:

var username = "thehalfheart";

Kiểu Array

Để khai báo kiểu Array trong TypeScript thì chúng ta có hai cách, cách thứ nhất chúng ta sử dụng cặp dấu [] đặt ở đằng sau kiểu dữ liệu.

let students: string[] = ["Cuong", "Kinh", "Chinh"];

Cách thứ hai chúng ta sử dụng từ khóa Array<type> để khai báo.

let students: Array<string> = ["Cuong", "Kinh", "Chinh"];

Kiểu Tuple

Tuple là kiểu dữ liệu đặc biệt có thể chứa nhiều giá trị với nhiều kiểu dữ liệu con khác nhau. Thực ra Tuple là một mảng nhưng đã xác định được số phần tử và kiểu dữ liệu cho mỗi phần tử đó. Ví dụ mình khai báo biên student gồm hai thông tin đó là tên và tuổi thì lúc này tên sẽ là kiểu string còn tuổi sẽ là kiểu number.

TypeScript

let student: [string, number] = ["Cuong", 27];

Kết quả Javascript:

var student = ["Cuong", 27];

Như vậy thực ra nó là một mảng gồm hai phần tử.

Kiểu Enum

Tương tự như trong C#, Enum là kiểu dữ liệu đặc biệt dùng để tạo một nhóm tên tương ứng với các giá trị là những con số mà ta thiết lập cho nó, cách này sẽ giúp ta dễ dàng nhớ tên hơn.

TypeScript:

enum Fruits {
  Orange,
  Banana,
  Mango,
  Apple,
}
let a: Fruits = Fruits.Orange;
alert(a);

Kết quả Javascript:

var Fruits;
(function (Fruits) {
  Fruits[(Fruits["Orange"] = 0)] = "Orange";
  Fruits[(Fruits["Banana"] = 1)] = "Banana";
  Fruits[(Fruits["Mango"] = 2)] = "Mango";
  Fruits[(Fruits["Apple"] = 3)] = "Apple";
})(Fruits || (Fruits = {}));
var a = Fruits.Orange;
alert(a);

Khi chạy chương trình này kết quả sẽ thông báo lên trình duyệt số 0 => như vậy nếu ta không thiết lập giá trị cho chúng thì nó sẽ tính theo thứ tự và bắt đầu bằng 0.

Bây giờ bạn đổi lại đoạn code TypeScript như sau:

TypeScript:

enum Fruits {
  Orange = 12,
  Banana,
  Mango,
  Apple,
}
let a: Fruits = Fruits.Orange;
alert(a);

Kết quả Javascript:

var Fruits;
(function (Fruits) {
  Fruits[(Fruits["Orange"] = 12)] = "Orange";
  Fruits[(Fruits["Banana"] = 13)] = "Banana";
  Fruits[(Fruits["Mango"] = 14)] = "Mango";
  Fruits[(Fruits["Apple"] = 15)] = "Apple";
})(Fruits || (Fruits = {}));
var a = Fruits.Orange;
alert(a);

Nhìn vào đoạn code biên dịch bạn dễ dàng đoán được số thứ tự sẽ bắt đầu từ 12. => Vậy để thiết lập giá trị cho từng phần tử thì ta gán trực tiếp cho chúng bằng dấu =

Kiểu Any

Đây là kiểu dữ liệu thoải mái nhất bởi nó cho phép bạn gán giá trị với kiểu dữ liệu bất kì, điều này giúp giải quyết rắc rối ở một số trường hợp, ví dụ ta cần lấy dữ liệu từ người dùng hoặc một thư viện khác thì ta không biết giá trị trả về sẽ ở kiểu dữ liệu nào nên ta sẽ sử dụng kiểu Any để tránh lỗi. Sau đây là một ví dụ từ trang chủ của nó.

TypeScript:

let notSure: any = 4; // kiểu number
notSure = "Thay thế bằng kiểu string";
notSure = false; // bây giờ lại là kiểu boolean

Kết quả Javascript:

var notSure = 4; // kiểu number
notSure = "Thay thế bằng kiểu string";
notSure = false; // bây giờ là kiểu boolean

Ngoài các dữ liệu đơn giản thì Any còn kết hợp được với cả các kiểu phức tạp, ví dụ:

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

Kiểu Void

Trong C# thì khi muốn khai báo một hàm không có giá trị trả về thì ta sẽ sử dụng hàm void, tuy ta hay gọi là hàm void nhưng thực ra nó là một kiểu dữ liệu với giá trị là null, trong TypeScript thì có thêm giá trị undefined.

function showMessage(): void {
  alert("Success!");
}

let unusable: void = undefined;

Kiểu Null và Undefined

Cả hai kiểu này đều là giá trị của kiểu void, và cũng tương tự thì hai kiểu này rất ít sử dụng trong quá trình xây dựng dự án.

let u: undefined = undefined;
let n: null = null;

Cách đặt tên biến trong TypeScript?


Có một số quy tắc trong khi khai báo biến:

  • Tên biến phải bắt đầu bằng một chữ cái
  • Tên biến có thể chứa chữ cái, chữ số, dấu _ và ký hiệu $.
  • Tên biến cũng có thể bắt đầu bằng $_
  • Các tên biến phân biệt chữ hoa chữ thường có nghĩa là aA là các biến khác nhau.
  • Không thể sử dụng các keywords cho các biến.

Ví dụ:

let isActive: boolean = false;
let decimal: number = 6;
let hex: number = 0xf00d;
let name: string = "Anil Singh";
let binary: number = 0b1010;
let octal: number = 0o744;
let numlist: number[] = [1, 2, 3];
let arrlist: Array = [1, 2, 3];

//Any Keyword
let list: any[] = [1, true, "free"];
list[1] = 100;

//Any Keyword
let notSureType: any = 10;
notSureType = "maybe a string instead";
notSureType = false;

Interface trong Typescript là gì?


Interface trong Typescript là gì

Interface trong typescript cho phép bạn định nghĩa thuộc tính là gì và phương thức là gì mà đối tượng cần để được thực thi (implement). Nếu đối tượng tuân thủ đúng khuôn mẫu interface thì đối tượng đã implement interface ấy sẽ được thi hành đúng. Nếu interface không được thi hành đúng đắn thì typescript sẽ phát sinh lỗi ngay lập tức. Để rõ hơn, bạn hãy xem những ví dụ và giải thích dưới đây:

function printLabel(labelObj: { label: string, size: number }) {
  console.log("Label: " + labelObj.label + " - Size: " + labelObj.size);
}
let _object = { size: 10, label: "Size 10 Object", _size: 1000 };
printLabel(_object);

Đây là một ví dụ không sử dụng interface. Chương trình sẽ tiến hành gọi hàm printLabel. Hàm printLabel sẽ yêu cầu hai tham số là labelsize. Hàm sẽ yêu cầu label là kiểu stringsize là kiểu number. Nếu bạn truyền sai kiểu, hàm sẽ không chạy được. Nhưng lưu ý rằng đối tượng object truyền vào có thể có nhiều thuộc tính nhưng trình biên dịch chỉ kiểm tra hai thuộc tính size và label mà hàm printLabel yêu cầu.

Dưới đây, bạn có thể tạo lại một hàm như trên sử dụng interface. Interface mô tả yêu cầu hai thuộc tính labelsize:

interface LabelValue {
  label: string;
  size: number;
}

function printLabel1(labelObj: LabelValue) {
  console.log("Label: " + labelObj.label + " - Size: " + labelObj.size);
}

let _object = { size: 10, label: "Size 10" };
printLabel1(_object);

Ngoài ra thì Interface sử dụng linh hoạt các thuộc tính nghĩa là đối tượng truyền vào có thể không cần truyền hết tham số yêu cầu, cái nào cần truyền thì truyền cái đó. Với việc thêm dấu ? sau tên thuộc tính của interface, ta đã sử dụng optional properties, có thể linh hoạt trong việc ghi thuộc tính cho đối tượng.

Ví dụ:

interface CircleConfig {
  color?: string;
  radius?: number;
  diameter?: number;
}
function createCircle(config: CircleConfig): {
  color: string;
  radius: number;
  diameter: number;
} {
  let newCircle = { color: "white", radius: 100, diameter: 1000 };
  if (config.color) {
    newCircle.color = config.color;
  }
  if (config.diameter) {
    newCircle.diameter = 2 * config.radius;
  }
  return newCircle;
}

let circle = createCircle({ color: "black", radius: 150, diameter: 1 });
console.log("diameter: " + circle.diameter);

Có một số thuộc tính không cho phép chỉnh sửa khi đối tượng khởi tạo. Bạn có thể đặt readonly trước tên thuộc tính. Ví dụ:

interface Point {
  readonly x: number;
  readonly y: number;
}

Anonymous function (hàm ẩn danh) là gì?


Một hàm ẩn danh là một hàm được khai báo mà không có bất kỳ định danh được đặt tên nào để tham chiếu đến nó.

// Ví dụ hàm bình thường

function printHello() {
  console.log("Hello Anil!");
}
printHello();

// Ví dụ Anonymous function JavaScript

var hello = function () {
  console.log("Hello Anil!, I am Anonymous.");
};
hello();
// Trả về - Hello Anil!, I am Anonymous. OR

setTimeout(function () {
  console.log("Hello Anil!, I am Anonymous.");
}, 2000);

// Trả về - Hello Anil!, I am Anonymous. TypeScript

var anonymousFunc = function (num1: number, num2: number): number {
  return num1 + num2;
};

console.log(anonymousFunc(10, 20)); // Trả về is 30

console.log(anonymousFunc(10, "xyz")); // error: Argument of type 'number' is not assignable to parameter of type 'string'.

// Bởi vì kiểu trả về là một số cho anonymous function).

Kết quả đoạn code sau là gì?

declare const iDontKnow: unknown;
if (typeof iDontKnow === string) {
  const aString: string = iDontKnow;
}

Nó sẽ không biên dịch. typeof trả về giá trị chuỗi, trong trường hợp mã ở trên typeof iDontKnow trả về giá trị 'chuỗi'. Nếu không, mã trên là tốt. Một không xác định có thể thuộc loại chuỗi và dấu kiểm nếu cho phép iDontKnow được gán cho một chuỗi const.

Avatar Techmely Team
VIẾT BỞI

Techmely Team