Latest Post

Tăng thứ hạng và truy cập tự nhiên với 10 phương pháp SEO hay nhất Kiếm Tiền Online (mmo): Khái Niệm và Các Hình Thức Phổ Biến

TypeScript cung cấp nhiều tính năng nâng cao về kiểu dữ liệu, giúp bạn tận dụng tối đa sức mạnh của hệ thống type. Bài viết này sẽ hướng dẫn về một số khái niệm quan trọng như kết hợp type, sử dụng các toán tử trên type và type guard.

Hệ thống type trong TypeScript không chỉ mạnh mẽ với việc giới thiệu nhiều kiểu dữ liệu mới mà còn với cách khai báo type đa dạng. TypeScript hỗ trợ nhiều toán tử hoạt động trên type như typeof, keyof, ?, |, &, giúp bạn linh hoạt hóa quá trình xử lý kiểu dữ liệu.

Bằng cách sử dụng những toán tử này, bạn có thể tạo ra những type mới phức tạp dựa trên những type đã có, mang lại khả năng mở rộng và tái sử dụng code một cách hiệu quả.

Tham khảo:

Kết hợp type – intersection type

Các kiểu dữ liệu khác nhau có thể kết hợp nhau để tạo nên một type mới có các thuộc tính của các kiểu thành viên. Thể hiện trong khai báo type bằng dấu &

type sinhvien = { 
   hoten: string; 
   ngaysinh: string; 
}
type hocbong = { 
   tenhb: string; 
   giatri: number;
}
type sinhviengioi = sinhvien & hocbong; 
let svg1: sinhviengioi = {
  hoten:"Nguyễn Văn Tèo", 
  ngaysinh:'2001-04-27',
  tenhb:'Xuất sắc học kỳ 2', 
  giatri:2000000  
};
console.log(svg1);

Kiểu sinhviengioi sẽ gồm các thuộc tính từ type sinhvien và type hocbong.

Nếu 2 type có thuộc tính giống nhau thì phải cùng kiểu dữ liệu. Lúc này 2 thuộc tính được xem như 1. Còn nếu hai thuộc tính cùng tên nhưng khác kiểu dữ liệu sẽ bị báo lỗi nhé bồ.

type hocvien = { hoten: string; dienthoai: string; ghichu:string; }
type khoahoc = { tenkhoa: string; khaigiang: string; ghichu:string }
type danghoc = hocvien & khoahoc; 
let hv1: danghoc = {
    hoten:"Nguyễn Thị Gia Hu",
    dienthoai:'0918123456',
    tenkhoa:'18.3',
    khaigiang:'2023-01',
    ghichu:'học viên dễ thương'
};
console.log(hv1);

Dùng toán tử typeof để chỉ định type cho biến

Trong TypeScript toán tử typeof để xác định kiểu dữ liệu của biến, từ đó có những tính toán thích hợp. Sau đây là một vài ví dụ sử dụng typeof.

Ví dụ 1: typeof dùng để xác định kiểu dữ liệu và tính toán

type T1 = number | string | boolean;
let x:T1; x= 1; 
console.log( typeof x ) ;
if ( typeof x =="number" ) x++; console.log (`x = `, x);

x = "Tháng Giêng"; console.log(typeof x);
x = true; console.log(typeof x);

Ví dụ 2: typeof dùng để xác định kiểu dữ liệu và tính toán

let str = "Hạnh phúc bây giờ";  
let kq = true;
console.log('Kiểu của biến str = ', typeof str);//string
console.log( typeof kq =='boolean' ? "Đậu":"Rớt");

Toán tử typeof trong TypeScript cũng có thể dùng trong ngữ cảnh type, để khai báo biến theo type của các biến khác. Ví dụ:

let gia1:unknown; gia1 = 25000;
console.log("Kiểu của gia1 = ", typeof gia1);//number
let km1: typeof gia1; //number
km1 = 1000;//ok

let gia2:any;  gia2 = "25000 đồng";
let km2: typeof gia2; //string
km2 = "1000 đồng"; //ok
console.log(`km1 = ${km1} , km2 = ${km2}`);

Dùng điều kiện trong định nghĩa type

Có thể diễn tả điều kiện với dấu ? trong định nghĩa type để chỉ định type linh động hơn. Cú pháp như sau:

type1 extends type2 ?  TrueType : FalseType;

Khi type1 thực sự extends từ type2 thì kết quả được sử dụng là type ở trước dấu hai chấm (Truetype) ngược lại là FalseType

interface MàuSắc { rgb(): void;}
interface MàuWeb extends MàuSắc { hsb(): void;}

type MàuĐẹp = MàuWeb extends MàuSắc ? string:number; //string
type GiaTriMau = BigInt extends MàuSắc ? string: number; //number
let x:MàuĐẹp='darkblue';
let y:GiaTriMau=59;

Lấy type của thuộc tính – Indexed Access type

Có thể lấy type của một thuộc tính nào đó trên 1 type khác để xác lập type mới. Sử dụng cú pháp type[‘key’] như code sau:

enum KhoaPhong { CAPCUU, NGOAI, NOI}
type BacSi = { tuoi: number; ten: string; khoa: KhoaPhong|string };
type TuoiBS = BacSi["tuoi"]; //number 
let x:TuoiBS = 36; //ok
type KhoaBV = BacSi["khoa"];
let y:KhoaBV = KhoaPhong.CAPCUU;
type T2 = BacSi[keyof BacSi]; // number| string | KhoaPhong
let u:T2 = KhoaPhong.NOI;

Type guard trong TypeScript

Trong TypeScript, type guard đảm bảo rằng xử lý dữ liệu sẽ chính xác với loại của biến.

Tại sao chúng ta cần type guard? Bởi vì trong TypeScript, có những biến được định kiểu là any hoặc unknown. Có các lớp được mở rộng từ các lớp khác. Có các kiểu union kết hợp từ nhiều kiểu khác nhau. Vì vậy, type guard là cần thiết để xử lý dữ liệu mà không gặp lỗi.

Nếu không có type guard, bạn có thể gặp vấn đề khi sử dụng toán tử ++ cho một biến kiểu string chẳng hạn. Các type guard thường được sử dụng bao gồm instanceof, typeof, in và nhiều loại khác.

Sử dụng instanceof

Dùng instanceof để kiểm tra xem một đối tượng nào đó có phải là một thể hiện, tức instance của một class hay không

class sinhvien { hoten:string; ngaysinh:string; }
class svgioi  extends sinhvien { hocbong:number; }
let sv1 = new sinhvien;
let svg = new svgioi;
let x:any = sv1;
console.log( sv1 instanceof sinhvien ); //true
console.log( sv1 instanceof svgioi ); //fasle
console.log( svg instanceof sinhvien ); //true
console.log( svg instanceof svgioi ); //true
console.log( x instanceof svgioi ); //false
console.log( x instanceof sinhvien ); //true

Sử dụng typeof

Đây là kiểu type guard thường dùng khi cần xác định kiểu dữ liệu của một biến. Toán tử typeof trả về các giá trị: boolean, string, bigint, symbol, undefined, function, number. Ngoài những cái này thì toán tử typeof sẽ trả về object.

Ví dụ sử dụng typeof để xác định kiểu của biến

Xác định xem biến thuộc kiểu nào để thực hiện tính toán thích hợp

type Thang = number | string ;
let t:Thang; 
t = 0;  if (typeof t =='number') t++; 
console.log(`t= `, t );

t = 'tháng giêng'; 
if (typeof t =='string') t = t.toUpperCase(); 
console.log(`t= `, t );

Dùng typeof để xác định xem 1 biến có phải là hàm không để chạy nó

Nếu typeof của 1 biến trả về là function thì biến đó là hàm. Lúc đó mới có  thể gọi hàm để chạy.

let f:any; console.log(typeof f); //undefined
f = "Mỗi ngày em hãy tìm một niềm vui"; 
console.log(typeof f); //string
if (typeof f ==='function') 
      console.log("Kết quả = " , f(1));
else  console.log("f không phải hàm, không chạy nhé");

f = (x:number):number => (x+2)*3; 
console.log(typeof f); //function
if (typeof f ==='function') 
     console.log("Kết quả = " , f(1));
else console.log("f không phải hàm, không chạy nhé");

Typeof xác định kiểu biến là symbol, BigInt

let f:any; console.log(typeof f); //underfine
f = Symbol('a'); console.log(typeof f); //symbol
f = BigInt(562); //Số lớn không giới hạn giá trị Number.MAX_SAFE_INTEGER
console.log(typeof f); //bigint

Sử dụng toán tử in xác định đối tượng chứa thuộc tính

Sử dụng toán tử in để xác định xem một đối tượng có chứa thuộc tính (attribute) hay không

interface màu { tênmàu:string; mãmàu:string; }
let x:màu = { tênmàu:'Đỏ', mãmàu:'#ff0000' }
console.log('id' in x); //false
console.log('tênmàu' in x); //true

Cần tham khảo thêm hãy xem ở đây https://www.typescriptlang.org/docs/handbook/2/types-from-types.html

Việc sử dụng kiểu dữ liệu nâng cao trong TypeScript là một phần quan trọng, nhưng còn một khái niệm khác mà chúng ta nên tìm hiểu, đó là generic trong TypeScript. Hãy đọc tiếp để hiểu rõ hơn về chủ đề này trong bài viết dưới đây.

3 thoughts on “Type nâng cao trong TypeScript

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *