Tổng hợp các ký hiệu trong typescript

1321
22-09-2022
Tổng hợp các ký hiệu trong typescript

Typescript là là một siêu tập hợp JavaScript được phát triển và duy trì bởi Microsoft. Nếu đang phát triển phần mềm bằng loại ngôn ngữ lập trình này thì bạn cần nắm vững được một số ký hiệu trong typescript dưới đây.

Unions type: |

Trong Javascript đây là toán tử OR.

ví dụ:

const a = 100;

const b = 001;

console.log(a | b);

output 101

Trong TypeScript ngoài việc nó vẫn là toán từ OR thì còn dùng định nghĩa Union type.

ví dụ:

let a: string | number;

a=1;

a="some text";

// đều không xảy ra lỗi, a có thể là string hoặc number đều được.

Intersection Types: & 

Tương tự như |, & cũng là 1 toán tử (AND) trong javascript.

Trong TypeScript, Intersection type kết hợp nhiều kiểu thành một. Điều này cho phép bạn thêm các kiểu hiện có lại với nhau để có được một kiểu duy nhất có tất cả các tính năng bạn cần.

Xem ví dụ dưới đây để hiểu thêm:

ví dụ

     interface ErrorHandling {

         success: boolean;

         error?: { message: string };

     }

     interface ArtworksData {

          artworks: { title: string }[];

     }

     interface ArtistsData {

         artists: { name: string }[];

     }

     // định nghĩa các interface riêng của Artwork, Artist và lỗi Error

     type ArtworksResponse = ArtworksData & ErrorHandling;

     type ArtistsResponse = ArtistsData & ErrorHandling;

      // ArtworksResponse khai báo như trên thì sẽ phải có cả 2 thuộc tính ArtworksData và ErrorHandling

      // ArtistsResponse khai báo như trên thì sẽ phải có cả 2 thuộc tính ArtistsData và ErrorHandling

     // ví dụ sử dụng:

     const handleArtistsResponse = (response: ArtistsResponse) => {

     if (response.error) {

            console.error(response.error.message);

         return;

     }

        console.log(response.artists);

     };

Numeric Separators: _ 

TypeScript 2.7 có hỗ trợ cho các dấu phân tách số.

Trong một ký tự số, bây giờ bạn có thể nhóm các chữ số bằng cách đặt dấu gạch dưới làm ký tự phân cách giữa chúng:

Ví dụ

     const worldPopulationIn2017 = 7_600_000_000;

     const ít nhấtSignificantByteMask = 0b1111_1111;

     const papayawhipColorHexCode = 0xff_ef_d5;

Các dấu phân cách không thay đổi giá trị của một số, nhưng việc nhóm hợp lý giúp người đọc số đó dễ dàng hơn.

Non-null assertion operator: ! – 

Là toán tử khẳng định, khẳng định rằng giá trị đang dùng không null hay undefined. Cụ thể, phép toán x! tạo ra một giá trị kiểu x với null và undefined bị loại trừ.

Ví dụ:

     interface Entity {

         name: string;

     }

     let x: Entity | null;

     // Tạo 1 hàm chấp nhận truyền vào là kiểu Entity hoặc null

     function processEntity(e?: Entity) {

         let s = e.name; // nếu dùng như này sẽ báo lỗi, vì e có thể có 2 kiểu là Entity hoặc null, nếu là null thì không truy vấn được name -> lỗi.

         // sửa thành như này:

         let s = e!.name; // e! khẳng định e không null, như thế có thể truy vấn được giá trị name. nhưng nếu e null thật, chương trình sẽ bị exception tại đây

         // vậy trước khi dùng e! cần kiểm tra xem e có null hay không.

     }

Optional notation: ?

Là ký hiệu tùy chọn đúng như tên gọi.

     Ví dụ

         function getHome(user) {

             return user.home.address

         }

            getHome({name: "autm", age: 50})

     Điều này sẽ gây ra lỗi runtime vì object {name: "autm",  age: 50} không có home.

     Dùng ? sẽ xử lý được lỗi này như sau.

         function getHome(user) {

             return user.home ? user.home.address: "không có nhà" // nếu home khác null hay undefine thì trả về giá trị address của home, nếu không thì trả về "không có nhà"

         }

         getHome({name: "autm",  age: 50})

         // output: "không có nhà"

Ngoài việc sử dụng ? để kiểm tra object có null hay undefine hay không bạn có thể dùng nó khi define 1 thuộc tính có hoặc không:

     ví dụ:

         interface User {

             name: string;

                address: string;

         }

         let anhA: User = User = {

             name: "autm",

         }

     Bạn sẽ nhận được thông báo lỗi.

     Lỗi này là do trình biên dịch mong đợi anhA bắt buộc phải khởi tạo 2 thuộc tính là name và address.

     Nhưng trong thực tế bạn chỉ muốn truyền giá trị "name" và giá trị "address" có thể là trường ko bắt buộc ,

     bạn có thể sửa bằng cách viết như sau:

         interface User {

             name: string;

                address?: string; // address có hoặc không đều được

         }

         let anhA: User = User = {

                name:"autm",

         }

Nullish coalescing operator: ?? – H2

Tương tự như 1 dấu ? nhưng ở đây lựa chọn của bạn ít hơn.

Ví dụ:

     let address = user.home ?? "không có nhà"; // address gán bằng giá trị của home trong user nếu nó khác null, nếu nó là null thì address gán bằng "không có nhà".

có thể viết bằng if else như sau:

     if  user.home == null {

         address "không có nhà";

     } else {

         address = user.home;

     }

Private property: #

Để báo cho trình biên dịch biết class có thuộc tính private thì ta viết # trước thuộc tính đấy :

ví dụ:

     class Car{

         #name: string;

            constructor(name: string) {

                this.#name = name

         }

         greet(){

                console.log(`Hello, this is ${this.#name}`)

         }

     }

Vậy # khác gì private?

     class Car {

         #name: string;

         private version: string;

            constructor(name: string, version: string) {

         this.#name = name;

            this.version = version;

         }

     }

Các thuộc tính khai báo từ khóa private sẽ tồn tại trong instance và chúng ta có thể truy cập được vào chúng dạng get only(không thể thay đổi giá trị từ ngoài)

Còn thuộc tính khai báo # sẽ ko lưu trữ trực tiếp trong instance nên không để truy cập vào chúng được.

Như ví dụ trên ta gọi.

     let json = new Car ("Toyota ex",  "2020");

        console.log((json as any).version); // 2020

        console.log((json as any).name); // undefined

Angle brackets: <>

Được dùng để định nghĩa kiểu dữ liệu, dù dùng trong trường hợp là Type assertions hay Generic types thì nó đều mang ý nghĩa là định nghĩa kiểu dữ liệu.

1. Type assertions

ví dụ:

     let code: any = 123;

     let employeeCode = code;

        console.log(typeof(employeeCode)); //Output: number, chắc chắn employeeCode là number mà không cần kiểm tra lại.

2. Generic types

ví dụ:

     function add(arg1: T,arg2: T) {

         return arg1 as any + arg2;

     }

     let x = add("string 1","string 2") // x :string 1 string 2, T ở đây sẽ là string

     let y = add(11,12)  // y: 23, T ở đây sẽ là number

Decorators: @

Decorators – nó là cái gì?

Decorator là một cách khai báo đặc biệt để có thể được đính kèm một số metadata khi khai báo các class, method, accessor, property hoặc các parameter.

Decorator sử dụng từ khóa @expression, trong đó expression là tên một function sẽ được gọi khi runtime với thông tin được khai báo trong decorator.

Bản chất của decorators chỉ là các hàm JavaScript, có thể được “hook” vào các class, method, accessor, properties hoặc parameters.

Ví dụ khi không sử dụng Decorator

     interface InitArguments {

         fuel: number;

     }

     class Rocket {

         fuel: number

            constructor(args: InitArguments) {

                this.fuel = args.fuel || 0

         }

     }

     class Ariane extends Rocket {}

     class RISAT extends Rocket {}

     const ariane = new Ariane({fuel: 100})

     const risat = new RISAT({fuel: 250})

Có sử dụng Decorators:

         function Init(args: InitArguments) {

             return (constructor: T) => {

                    return class extends constructor {

                        fuel = args.fuel || 0

                 }

             }

         }

         interface InitArguments {

             fuel: number;

         }

         class Rocket {

             fuel: number

         }

            @Init({fuel: 100}) // Decorators ở đây, khi gọi RISAT thì function Init được gọi luôn với fuel 100

        class Ariane extends Rocket {}

            @Init({fuel: 250}) // Decorators ở đây, khi gọi RISAT thì function Init được gọi luôn với fuel 250

         class RISAT extends Rocket {}

         const ariane = new Ariane() // ngắn gọn hơn so với  new Ariane({fuel: 100})

         const risat = new RISAT() // ngắn gọn hơn so với  new RISAT({fuel: 250})

Kết: 

Hi vọng những chia sẻ trên đã giúp bạn có thêm những kiến thức quan trọng về ngôn ngữ lập trình Typescript. Từ đó, ứng dụng chúng tốt hơn trong công việc và học tập. 

SHARE