hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Angular
  • Học lập trình
  • Lập trình Javascript
Một số kỹ thuật TypeScript Nâng Cao

Một số kỹ thuật TypeScript Nâng Cao

  • 21-12-2023
  • Toanngo92
  • 0 Comments

Mục lục

  • Union Type là gì?
  • typeof là gì?
  • Intersection Type là gì?
  • Conditional Type là gì?
  • Type Alias là gì?
  • Type Alias và Union Type
  • Type Alias và Conditional Type

Union Type là gì?

Union Type trong TypeScript cho phép bạn định nghĩa các kiểu dữ liệu có tính chất “HOẶC”. Đây là cách để chỉ định rằng một biến có thể mang một trong các kiểu dữ liệu đã được định nghĩa. Để tạo Union Type, chúng ta sử dụng ký hiệu “Pipe Symbol” (|).

Ví dụ, hãy xem xét một hàm listen() như sau:

function listen(port: unknown) {
  if (typeof port === "string") {
    port = parseInt(port, 10);
  }
  server.listen(port);
}

Trong ví dụ này, tham số port được định kiểu là unknown, có nghĩa là nó có thể chứa nhiều loại kiểu dữ liệu khác nhau. Bằng cách sử dụng typeof để kiểm tra nếu port là kiểu “string”, chúng ta thực hiện việc chuyển đổi port thành số nguyên nếu có thể. Điều này cho thấy khả năng của Union Type khi một biến có thể là string hoặc số nguyên, giúp chúng ta xử lý linh hoạt hơn trong các tình huống khác nhau.

typeof là gì?

Operator typeof trong TypeScript được sử dụng để trả về kiểu dữ liệu của một biến hoặc giá trị cụ thể. Kết quả trả về từ typeof luôn có kiểu là string.

typeof "string"; // string
typeof 123; // number
typeof true; // boolean
typeof {}; // object
typeof []; // object
typeof (() => {}); // function
typeof null; // object
typeof undefined; // undefined
typeof new Date(); // object
typeof String; // function
typeof Boolean; // function
typeof NaN; // number
typeof typeof 123; // string

Khi áp dụng typeof trong hàm listen(), tham số port có kiểu unknown, cho phép chúng ta truyền vào một loại kiểu dữ liệu không xác định khi viết mã. Hàm này có thể nhận nhiều loại kiểu dữ liệu như string, number, boolean, mảng, object và function (bao gồm cả undefined và null).

unknown là một kiểu dữ liệu được giới thiệu trong TypeScript 3.0 và khuyến nghị sử dụng unknown thay vì any khi không biết chính xác kiểu dữ liệu của biến.

Tuy nhiên, trong trường hợp hàm listen() chỉ xử lý hai kiểu dữ liệu string và number, việc sử dụng unknown trở nên không linh hoạt. Đây là lúc Union Type được áp dụng để xác định chính xác các kiểu dữ liệu hợp lệ.

function listen(port: string | number) {
  // xử lý
}
listen("3000"); // ok
listen(3000); // ok
listen(true); // TypeError: Kiểu dữ liệu true không thể gán cho tham số kiểu string | number
listen(); // TypeError: Số lượng đối số không hợp lệ, cần 1 đối số

TypeScript sẽ báo lỗi ngay lập tức (Compilation Time Error) nếu bạn truyền vào kiểu dữ liệu không hợp lệ khi gọi hàm listen(). Mặc dù sau khi biên dịch sang JavaScript, bạn có thể chạy được code nhưng sẽ gặp lỗi tại thời điểm chạy (Runtime Error).

Tạo Union Type cho giá trị trả về của hàm cũng tương tự như tạo Union Type cho tham số. Điều này cho phép tái sử dụng một Union Type bằng cách tạo Type Alias cho nó.

Intersection Type là gì?

Intersection Type trong TypeScript là một loại type cho phép kết hợp nhiều type lại với nhau. Nó tương đương với toán tử “AND” trong logic.

Ví dụ, hãy xem xét hàm merge() sau:

function merge<T1, T2>(o1: T1, o2: T2): T1 & T2 {
  return { ...o1, ...o2 };
}
merge({ foo: "bar" }, { bar: "foo" });

Trong ví dụ này, hàm merge() nhận vào hai đối tượng và trả về kết quả là kết hợp của hai loại đối tượng đó. Khi gọi hàm merge({ foo: 'bar' }, { bar: 'foo' }), kết quả trả về sẽ có kiểu dữ liệu { foo: string } & { bar: string }.

Intersection Type không chỉ được sử dụng trong các hàm thông thường mà không phù hợp với khái niệm OOP, mà còn thường được áp dụng trong việc thiết kế hệ thống type cho các thư viện UI Components.

Ví dụ, trong đoạn code dưới đây, chúng ta có hai loại Props cho Button và Text, mỗi loại có các thuộc tính riêng biệt và cũng chia sẻ một số thuộc tính giống nhau từ type StyleProps:

type StyleProps = {
  backgroundColor: string;
  color: string;
  margin: string;
  padding: string;
  // ...
}

type ButtonProps = {
  onClick: (event: MouseEvent) => void;
} & StyleProps;

type TextProps = {
  fontSize: string;
  fontWeight: number;
  // ...
} & StyleProps;

Trong trường hợp này, các thành phần UI như Button và Text có những loại Style khác nhau nhưng lại chia sẻ một số thuộc tính giống nhau. Sử dụng Intersection Type cho phép kết hợp các type này một cách linh hoạt mà không cần phải lặp lại những thuộc tính chung nhiều lần. Điều này giúp tạo ra một cách viết code sáng tạo hơn và tiết kiệm thời gian.

Type Composition, hay còn được gọi là Intersection Type, là một chủ đề rất quan trọng và rộng lớn trong TypeScript. Để hiểu rõ hơn về nó, bạn có thể tìm kiếm thêm thông tin trên Internet để tự tìm hiểu và áp dụng trong thực tế.

Conditional Type là gì?

Conditional Type trong TypeScript là một tính năng mạnh mẽ được giới thiệu từ phiên bản 2.8. Đây là một tính năng đặc biệt, cho phép chúng ta tạo ra các loại dữ liệu theo các điều kiện nhất định. Điều này mang lại một hệ thống type cực kỳ linh hoạt và mạnh mẽ cho TypeScript.

Ví dụ cơ bản về Conditional Type là:

T extends U ? X : Y;

Đoạn code này có ý nghĩa rằng nếu type T có thể gán được cho type U, thì kết quả trả về sẽ là type X, ngược lại nếu không thì sẽ trả về type Y. Điều này cho phép chúng ta điều khiển việc gán giá trị cho các type một cách linh hoạt dựa trên các điều kiện logic.

Type Alias là gì?

Type Alias trong TypeScript cho phép bạn tạo ra tên thay thế cho một hoặc nhiều loại dữ liệu, giống như việc tạo Type Alias StringOrNumber cho union type string | number. Nó cho phép bạn tạo tên gọi mới để đại diện cho một hoặc nhiều loại dữ liệu khác nhau trong mã của bạn. Alias này có thể được sử dụng cho bất kỳ loại dữ liệu nào bạn muốn.

Type Alias và Union Type

Đây là một ví dụ về việc sử dụng Type Alias để áp dụng cho Union Type. Giả sử chúng ta cần tạo một component Flex với một số yêu cầu nhất định:

  • Flex có style mặc định là display: 'flex'
  • Flex nhận một Input là flexDirection để áp dụng vào style, ví dụ: flex-direction: flexDirection
type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';

@Component({
  selector: 'flex-container',
  template: `<ng-content></ng-content>`
})
export class FlexComponent {
  @Input() flexDirection: FlexDirection = 'row';
  @HostBinding('style.display') get display() {
    return 'flex';
  }
  @HostBinding('style.flex-direction') get direction() {
    return this.flexDirection;
  }
}

Ở đây, chúng ta đã tạo một Type Alias là FlexDirection, đại diện cho các giá trị có thể của flexDirection trong FlexComponent. Bằng cách này, TypeScript sẽ gợi ý cho chúng ta 4 giá trị có thể của flexDirection khi sử dụng component này trong template.

<flex-container>
  <button>Submit</button>
  <button>Cancel</button>
</flex-container>
<flex-container flexDirection="column">
  <input type="email" />
  <input type="password" />
</flex-container>

Khi sử dụng component FlexContainer trong template, TypeScript sẽ gợi ý (intellisense) các giá trị của flexDirection để giúp bạn dễ dàng truyền giá trị hợp lý cho flexDirection.

Type Alias và Conditional Type

Đây là một ví dụ về việc sử dụng Type Alias kết hợp với Conditional Type cùng với một số built-in types trong TypeScript.

type ObjectDictionary<T> = { [key: string]: T };
type ArrayDictionary<T> = { [key: string]: T[] };
export type Dictionary<T> = T extends []
  ? ArrayDictionary<T[number]>
  : ObjectDictionary<T>;

type StringDictionary = Dictionary<string>; // {[key: string]: string}
type NumberArrayDictionary = Dictionary<number[]>; // {[key: string]: number[]}
type UserEntity = Dictionary<User>; // {[key: string]: User}

Ở ví dụ trên, chúng ta đã định nghĩa ba loại Type Alias: ObjectDictionary, ArrayDictionary, và Dictionary. Trong đó, Dictionary có thể coi là True Type, còn ObjectDictionary và ArrayDictionary được sử dụng để hỗ trợ cho True Type. Điều quan trọng là code này rất dễ hiểu, nói rõ ràng rằng nếu chúng ta truyền vào một type dạng number[] cho type parameter T ở Dictionary<T> thì T extends[] sẽ được đánh giá là true, và Dictionary<number[]> sẽ trả về type ArrayDictionary<number>.

Ngoài ra, TypeScript cũng cung cấp một số built-in types rất hữu ích như Exclude, Extract, Readonly, Partial, Nullable, Pick, Record, ReturnType, và Omit:

// Các built-in types
type SomeDiff = Exclude<"a" | "b" | "c", "c" | "d">; // 'a' | 'b'. 'c' đã bị loại bỏ.
type SomeFilter = Extract<"a" | "b" | "c", "c" | "d">; // 'c'. 'a' và 'b' đã bị loại bỏ.

type NonNullable<T> = Exclude<T, null | undefined>; // loại bỏ null và undefined từ T
type Readonly<T> = { readonly [P in keyof T]: T[P] };
type Partial<T> = { [P in keyof T]?: T[P] };
type Nullable<T> = { [P in keyof T]: T[P] | null };

type Person = {
  firstName: string;
  lastName: string;
  password: string;
};
type PersonWithNames = Pick<Person, "firstName" | "lastName">; // {firstName: string, lastName: string}

type ThreeStringProps = Record<"prop1" | "prop2" | "prop3", string>; // { prop1: string, prop2: string, prop3: string }

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; // Trả về type của giá trị mà function T trả về.
type Result = ReturnType<() => string>; // string

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; // loại bỏ type có key là K trong T
type PersonWithoutPassword = Omit<Person, "password">; // {firstName: string, lastName: string}

Các built-in types này cung cấp cho chúng ta rất nhiều khả năng linh hoạt khi tạo và sử dụng các loại type phức tạp trong TypeScript.

Bài viết liên quan:

Sắp xếp sủi bọt – Bubble Sort
TypeScript với Kiểu Dữ Liệu Cơ Bản – 3
TypeScript với Kiểu Dữ Liệu Cơ Bản – 2
TypeScript với Kiểu Dữ Liệu Cơ Bản – 1
Typescript cơ bản và cách cài đặt cho người mới
Thực Hành Micro Frontends
Dynamic Component trong Angular
Async Validator trong Angular Form
Reactive Forms Trong Angular (Phần 2)
Reactive Forms Trong Angular (Phần 1)
Template-driven Forms Trong Angular (Phần 2)
Template-driven Forms Trong Angular (Phần 1)

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

2. PHÂN TÍCH VÀ ĐẶC TẢ HỆ THỐNG

1. TỔNG QUAN KIẾN THỨC THỰC HÀNH TRIỂN KHAI DỰ ÁN CÔNG NGHỆ THÔNG TIN

Hướng dẫn tự cài đặt n8n comunity trên CyberPanel, trỏ tên miền

Mẫu prompt tạo mô tả chi tiết bối cảnh

Một số cải tiến trong ASP.NET Core, Razor Page, Model Binding, Gabbage collection

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×