Master typescript
Contents
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) { ... }