Typescript and Friends – Phần 1: Typescript Types

4 min read

Mở đầu

Typescript – A Typed Superset of JavaScript

Typescript là một phiên bản mở rộng của Javascript, cho phép lập trình viên phát hiện các lỗi về syntax trong code một cách nhanh chóng mà không cần phải chạy thử (static checking).

const obj = { width: 10, height: 15 };
const area = obj.width * obj.heigth;
// Property 'heigth' does not exist on type '{ width: number; height: number; }'. Did you mean 'height'?

Như mọi người thấy TypeScript làm cho những dòng code Javascript của chúng ta trở nên chặt chẽ hơn, xác định ngay cho chúng ta biết rằng những kiểu dữ liệu cho biến nào đang thiếu chính xác. Nhờ sự tiện lợi đó thì lập trình viên không thể bỏ qua được ngôn ngữ này.

Đây là series Typescript and Friends của mình, trong series này, mình sẽ trình bày từ tổng quan đến chi tiết về typescript cũng như các tool, library giúp typescript mạnh mẽ hơn. Ở bài viết đầu tiên, mình sẽ giới thiệu tổng quan về các type trong typescript và cách sử dụng của chúng. Không dài dòng nữa, bắt đầu thôi!

Basic Types

Primitive Type

string – Kiểu chuỗi, number – Kiểu số, boolean – Kiểu chứa 2 giá trị truefalse.

const str: string = 'Hello';
const num: number = 69;
const bool: boolean = false;

Array Type

const array1: number[] = [1, 2, 3, 4, 5];
const array2: Array<number> = [1, 2, 3, 4, 5];

Object Type

type ObjectType = {
  prop1: number;
  prop2: string;
}
const obj: ObjectType = {prop1: 1, prop2: 'Hello'};

Đối tượng bên trong 1 đối tượng

type NestedObj = {
  prop1: number;
  prop2: {
    nestedProp: string;
  }
}
const nestedObj: NestedObj = {prop1: 1, prop2: {nestedProp: 'a'}};

Đối tượng có thuộc tính tùy chọn (có thể chứa thuộc tính đó hoặc không)

type OptionalPropObj = {
  prop1: number;
  optionalProp?: number;
}
let optionalPropObj: OptionalPropObj = {prop1: 1};
optionalPropObj = {prop1: 1, optionalProp: 2};

Types trong Function

// greet function has 1 parameter `name` with type `string` and return a `string` as well
function greet(name: string): string {
  return 'Hello, ' + name.toUpperCase() + '!!';
}

Advanced Types

Typescript cho phép lập trình viên tạo ra các type mới từ các type có sẵn bằng cách kết hợp chúng với nhau sử dụng các toán tử được cung cấp bởi typescript.

Union Type

Được tạo thành từ 2 hay nhiều type khác nhau, biểu diễn một giá trị có thể là bất kỳ type nào trong số các type thành phần. Mỗi type thành phần tạo nên Union Type được gọi là union’s member.

type Animal = 'bird' | 'cat' | 'fish';
const anm1: Animal = 'cat'; // ok
const anm2: Animal = 'bird'; // ok
const anm3: Animal = 'fish'; // ok
const anm4: Animal = 'dog'; // Type '"dog"' is not assignable to type 'Animal'.

Intersection Type

Cũng tương tự như Union Type, Intersection Type được tạo thành từ 2 hay nhiều type khác nhau, điểm khác biệt ở đây là Intersection Type sẽ bao gồm tất cả các đặc tính của các type mà chúng ta đã tạo trước đó.

type Identity = {
  id: number;
  name: string;
}

type Contact = {
  email: string;
  phone: string;
}

// intersection type
type Employee = Identity & Contact;
const e: Employee = {
  id: 100,
  name: 'Duc',
  email: 'duc@example.com',
  phone: '0123456789'
};

Interface

Ngoài Object Type, Interface là cách khác để biểu diễn cấu trúc của một object.

interface Employee {
  id: number;
  name: string;
  email: string;
  phone: string;
}
const e: Employee = {
  id: 100,
  name: 'Duc',
  email: 'duc@example.com',
  phone: '0123456789'
};

Để sử dụng lại các thuộc tính từ một interface đã có, chúng ta có thể extends interface đó.

interface Animal {
  name: string;
}

interface Bear extends Animal {
  honey: boolean;
}

Special Types

any

Đúng như tên, chúng ta có thể gán cho biến được khai báo với type này bất kỳ giá trị nào mà không cần phải lo lắng đến lỗi kiểm tra kiểu của typescript

let animal: any = { name: 'cat' };
// None of the following lines of code will throw compiler errors.
animal.fly();
animal();
animal.wing = 'long wing';
animal = "hello";

null và undefined

Đại diện cho 2 giá trị nullundefined trong javascript

let name: string | null | undefined;
name = 'Duc';
name = null;
name = undefined;

unknown

Tương tự như any, unknown đại diện cho bất kỳ giá trị nào. Tuy nhiên sử dụng unknown an toàn hơn any vì chúng ta không thể thao tác trên một biến có kiểu unknown.

function f1(a: any) {
  a.b(); // ok
}
function f2(a: unknown) {
  a.b(); // not ok, 'a' is of type 'unknown'.
}

never

Như tên gọi của nó nghĩa là không bao giờ xảy ra. Các trường hợp có type never

  • Hàm bắn ra lỗi nào đó và không có return.
  • Hàm có sử dụng vòng lặp vô tận và cũng không có return.
  • Không còn bất kỳ một giá trị nào trong union.
function fail(msg: string): never {
  throw new Error(msg);
}

function keepProcessing(): never {
  while (true) {
    console.log("I always does something and never ends.");
  }
}

function fn(x: string | number) {
  if (typeof x === "string") {
    // do something
  } else if (typeof x === "number") {
    // do something else
  } else {
    x; // has type 'never'!
  }
}

void

Đại diện cho giá trị trả về của một function mà không trả về giá trị nào.

// implicit void return type
function imNoop() {
  return;
}
// explicit void return type
function exNoop(): void {
  return;
}

Tổng kết

Trên đây là phần chia sẻ của mình, hi vọng sẽ giúp mọi người có một cái nhìn tổng quan về typescript cũng như hiểu thêm về cách sử dụng các type trong typescript. Hẹn gặp lại mọi người ở các bài viết tiếp theo. See ya.

Mọi người có thể tìm hiểu thêm về type trong typescript ở đây: https://www.typescriptlang.org/docs/handbook/2/everyday-types.

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *