Thumbnail
Category: Lập trình

Master typescript

Date: April 13, 2025
94 views


1. Run typescript

tsc fileName.ts
node fileName.js
  
// nếu install type của bên thứ ba thì sử dụng @types
npm i --save-dev @types/lodash

Webpack

npm install --save-dev webpack webpack-cli typescript ts-loader
  
// config webpack.config.js
webpack --config tenFileConfig

// EX:
webpack --config webpack.dev.js
webpack --config webpack.prod.js


tsconfig

// Các thuộc tính cần lưu ý với tsconfig.json

target => version javascript
includes => danh sách file, folders
outputDir
sourceMap => gỡ lỗi

2. Type basic

let myVar: type = value

Primitive Types:

- Number, String. Boolean

- Null. Undefined, Void

- Any, Never, Unknown

Type inference

=> TS tự động khai báo kiểu dữ liệu dựa trên value của biến.

VD: let x = 5; => x có type number

let variable;

=> variable có type là any

Function type sau parameter.

Vd: const add = (x: number, y: number) : number {
   return x + y;
}


3. Object type

3.1 Alias type

// VD:
// Thay vì:
let point: {x: number, y: number} = {x: 34, y: 2}

// Thì:
type Point = {
 x: number;
 y: number;
};

let point: Point = {x: 34, y: 2};

3.2 Nested object

type Song = {
  title: string;
  artist: string;
  credits: {
     producer: string; 
     writer: string
  }
};

3.3 Optional properties

type Point = {
 x: number;
 y: number;
 z?: number;
};

3.4 Readonly properties

type User = {
 readonly id: number;
 username: string;
};

3.5 Intersection type

type Circle = {
  radius: number;
};

type Colorful = {
  color: string;
};

type ColorfulCircle = Circle & Colorful;


type Cat = {
  numLives: number;
};

type Dog = {
  breed: string;
};

type Animal = Cat & 
      Dog &
      {
        age: number;
      };


4. Array type

const activeUsers: string[] = ["John"];
const ageList: number[] = [45, 56];

4.1 Multi dementional (array nhiều cấp)

const board: string[][] = [
  ["X", "O", "X"],
  ["X", "O", "X"],
  ["X", "O", "X"],
];


type Board = [
  [string, string, string],
  [string, string, string],
  [string, string, string],
  number,
  string
];

const board: Board = [ 
  ["X", "O", "X"],
  ["X", "O", "X"],
  ["X", "O", "X"],
  3, // number row
  "title"
];


// ❌ Lỗi khi dùng dấu ;

type Board = [
  [string; string; string]; // ❌ Sai cú pháp
  [string; string; string]; // ❌ Sai cú pháp
  [string; string; string]; // ❌ Sai cú pháp
  number;
  string
];

// ⛔ Lỗi: TypeScript sẽ báo lỗi vì ; không hợp lệ trong khai báo kiểu.

// 📌 Lưu ý: Dấu ; chỉ được sử dụng trong interface hoặc type object như sau:

type User = {
  name: string;
  age: number;
};

// Nhưng trong mảng hoặc tuple, bạn phải dùng dấu ,


5. Union type

let age: number | string = 21;


// Sử dụng typeof để check type
VD: typeof age === 'string'


5.1 Với array

const stuff: (number | string)[] = [1, 2, 3, "dog"]

Cần phân biệt:

// mảng chứa item kiểu number hoặc string
const stuff: (number | string)[] = [1, 2, 3, "dog"]

// Là số hoặc mảng kiểu chuỗi
const stuff: number | string[] = 2

// là mảng số hoặc là mảng chuỗi
const stuff: number[] | string[] = [1, 2, 3]

5.2 Literal type

dạng như hằng số, value nó phải giống với đã định nghĩa.
// VD:
function result( answer: "yes" | "no") : void {
}

type DayOfWeek = "Monday" | "Tuesday" | ...


6. Tuples And Enums

6.1 Tuples

Tuples định nghĩa số lượng và type của từng vị trí.

// VD:
const color: [number, number, number] = [255, 0, 45];

type HTTPResponse = [number, string];
const goodRes: HTTPResponse = [200, "OK"];

Lưu ý: Typescript không complain khi sử dụng push() or pop(), mặc dù nó làm thay đổi cấu trúc.

// VD: 
goodRes.push(123).

6.2 Enums

Định nghĩa constant
enum OrderStatus {
  PENDING,
  SHIPPED,
  DELIVERED,
  RETURNED,
}

const myStatuts = OrderStatus.DELIVERED;

6.2.1 Default value

Nếu không có value thì mặc định value bắt đầu có giá trị là 0

enum OrderStatus {
  PENDING, // 0
  SHIPPED, // 1
  DELIVERED, // 2
  RETURNED, //3
}

Khi có định nghĩa value sẽ tăng lên 1 đơn vị từ chỗ định nghĩa

enum OrderStatus {
  PENDING, // 0
  SHIPPED = 5, // 5
  DELIVERED, // 6
  RETURNED, // 7
}

Có thể định nghĩa value cho từng item.

enum OrderStatus {
  PENDING = "pending",
  SHIPPED = 5,
  DELIVERED = 7,
  RETURNED = 8,
}

Sẽ lỗi nếu item trống sau item có value chuỗi.

enum OrderStatus {
  PENDING = "pending",
  SHIPPED,
  DELIVERED = 7,
  RETURNED = 8,
}

// SHIPPED => lỗi, do tự động tăng 1 đơn vị nhưng trước nó là chuỗi, không tăng được.


7. Interface

Chỉ sử dụng cho object

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

Định nghĩa có method:

interface Product {
  name: string;
  price: number;
  applyDiscount(discount: number): number;
}

// hoặc
interface Product {
  name: string;
  price: number;
  applyDiscount: (discount: number) => number;
}


7.1 Ghi đè interface

Type sẽ báo lỗi nếu định nghĩa lại type đã có, còn interface sẽ thêm mới vào chớ không ghi đè.

interface Dog {
  name: string;
  age: number;
}

interface Dog {
  breed: string;
  bark(): string;
}

// Khi tạo đối tượng type Dog sẽ có cả name, age, breed và bark


7.2 Extend

interface ServiceDog extends Dog {
  job: "drug sniffer" | "bomb";
}

// multi extends
interface ServiceDog extends Dog,Animal {
  job: "drug sniffer" | "bomb";
}


7.3 Q/A

7.3.1 Có type rồi, vậy sinh ra interface để làm gì?

interface dùng như OOP để có thể mở rộng, chuyên dùng để mô tả cấu trúc của đối tượng.

7.3.2 Type thì có add method như interface được không?

Có.

type User = {
 id: number;
 name: string;
 greet(): string;
};

interface User {
 id: number;
 name: string;
 greet(): string;
}


7.3.3 Nếu thêm thuộc tính đã có với kiểu dữ liệu khác thì cuối cùng nó sẽ là gì?

// TypeScript sẽ gộp lại nếu thuộc tính trùng tên, khác kiểu dữ liệu.

interface User {
 id: number;
 name: string;
 greet(): string;
}

interface User {
 age: number;
 name: number;
}

// => cuối cùng
interface User {
 id: number;      // Từ khai báo đầu tiên
 name: string | number; // Hợp nhất thành union type
 greet(): string;    // Từ khai báo đầu tiên
 age: number;      // Từ khai báo thứ hai
}


8. Config typescript

tsc --init

// => sẽ tạo ra file tsconfig.json
// Có thể config files, include, exclude những file cần biên dịch
// Outdir => nơi lưu file build ra
// Target => chỉ định version javascript
  
  
// Watch
tsc -w filename.ts
tsc -w folder


9. Làm việc với DOM

9.1 Toán tử khẳng định không null

const btn = document.getElementById('btn-submit')!;

// => btn luôn luôn là HTMLElement không bao giờ là null

9.2 Type Assertions (Ép kiểu)

const dog: unknown = "";
const length = (dog as string).length;


const input = document.getElementById('todo')! as HTMLInputElement;

// hoặc
(<HTMLInputElement>input).value;

9.3 Event

function handleSubmit (e: SubmitEvent) {
  e.preventDefault();
}

form.addEventListionner('submit', handleSubmit);


10. Generic

cú pháp: <type>

// VD:
document.querySelector<HTMLInputElement>('input')!;


function identity<Type>(item: Type): Type {
  return item;
}

identity<number>(7)
identity<string>(7)

// code gọn
function identity<T>(item: T): T{
  return item;
}


10.1 Lưu ý trong React

Lưu ý trong React, nó sẽ tưởng là HTML. => nên hãy thêm dấu "," phía sau

const identity = <T,>(item: T): T => {
  ...
}


10.2 Multi type

function merge<T,U>(object1: T, object2: U) {
  return {
   ...object1,
   ...object2,
  }
}

const comboObj = merge(
  { name: 'colt' },
  { type: 'dog' }
)

Chỉ định type với từ khóa extends

function merge<T extends object, U extends object>(object1: T, object2: U) {
  return {
   ...object1,
   ...object2,
  }
}


10.3 Default type

function identity<T = number>(item: T): T{
  return item;
}


11. Type narrow (thu hẹp kiểu dữ liệu)

11.1 Toán tử in

=>Sử dụng để check thuộc tính có tồn tại trong object không.

// Ex:
const cat = { name: 'Eble', age: 20};
"name" in cat // true
"isDie" in cat // false

11.2 Toán tử instanceof

=> sử dụng để check biến có được tạo từ 1 class không (có là đối tượng không)

if (date instanceof Date) {
  ...
}

11.3 Type predicates

=> viết hàm để check type

interface Cat {
  numLives: number;
}

interface Dog {
  name: string;
}

function isCat(animal: Cat | Dog): animal is Cat {
  return (animal as Cat).numLives !== undefined;
}

if (isCat(animal) {
 ...
}

Copyright © 2025 All Right Reserved