Dark mode
TypeScript
TypeScript เป็นภาษาที่มีความยืดหยุ่นและสามารถใช้ได้กับโครงการขนาดใหญ่หรือเล็ก โดยมีเครื่องมือและไลบรารีต่างๆ ที่รองรับการพัฒนา
ประโยชน์ของ TypeScript
คุณสมบัติหลัก | รายละเอียด |
---|---|
การตรวจสอบชนิดข้อมูล | ตรวจสอบชนิดข้อมูลขณะคอมไพล์ ช่วยลดข้อผิดพลาดขณะรันโปรแกรม |
การเขียนโปรแกรมเชิงวัตถุ | รองรับ class, interface, inheritance สำหรับการออกแบบระบบ |
เครื่องมือพัฒนาขั้นสูง | มี autocomplete, refactoring และ IntelliSense ที่แม่นยำ |
ทำงานร่วมกับ JavaScript | สามารถใช้โค้ด JavaScript ที่มีอยู่ได้ทันที |
จัดการโครงการขนาดใหญ่ | โครงสร้างโค้ดที่ชัดเจน ช่วยให้ทีมทำงานร่วมกันได้ดี |
ระบบนิเวศที่แข็งแกร่ง | มีไลบรารีและเฟรมเวิร์กมากมายที่รองรับ TypeScript |
ฟีเจอร์ ECMAScript ล่าสุด | สามารถใช้ฟีเจอร์ใหม่ๆ ของ JavaScript ก่อนที่เบราว์เซอร์จะรองรับ |
เอกสารอัตโนมัติ | ระบบ Type ช่วยสร้างและดูแลเอกสารอัตโนมัติ |
TypeScript ช่วยเพิ่มประสิทธิภาพการทำงานของทีมพัฒนาด้วยการทำให้โค้ดอ่านเข้าใจง่ายขึ้นและลดข้อผิดพลาดที่พบได้บ่อยในการพัฒนา JavaScript
Installation
Install TypeScript using your preferred package manager:
bash
npm install -D typescript
bash
pnpm add -D typescript
bash
yarn add -D typescript
bash
bun add -d typescript
Installation is the first step to start using TypeScript.
How TypeScript Works
กระบวนการทำงานของ TypeScript:
- เขียนโค้ด TypeScript (.ts)
- Type Checker ตรวจสอบชนิดข้อมูล
- หากถูกต้อง จะคอมไพล์เป็น JavaScript (.js)
- หากมีข้อผิดพลาด จะแสดง Error Messages
- โค้ด JavaScript ที่ได้ทำงานใน Runtime
Configuration
การสร้างไฟล์ tsconfig.json เป็นขั้นตอนสำคัญในการตั้งค่า TypeScript
bash
# สำหรับโปรเจคที่ใช้ npm
npx tsc --init
bash
# สำหรับโปรเจคที่ใช้ pnpm
pnpm dlx tsc --init
bash
# สำหรับโปรเจคที่ใช้ yarn
yarn dlx tsc --init
bash
# สำหรับโปรเจคที่ใช้ bun
bunx tsc --init
ตัวอย่างไฟล์ package.json พื้นฐานสำหรับโปรเจค TypeScript:
json
{
"name": "my-typescript-project",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"start": "node dist/index.js"
},
"devDependencies": {
"typescript": "^5.0.0"
}
}
หรือสร้างไฟล์ด้วยคอนฟิกพื้นฐาน:
json
{
"compilerOptions": {
// กำหนดเวอร์ชัน JavaScript ที่ต้องการ (ES3, ES5, ES6/ES2015, ESNext ฯลฯ)
"target": "ESNext",
// ระบบโมดูลที่ใช้ (CommonJS, ES6, AMD, UMD, System ฯลฯ)
"module": "ESNext",
// เปิดโหมดตรวจสอบชนิดข้อมูลแบบเข้มงวด
"strict": true,
// ทำให้การทำงานร่วมกับโมดูล ES6 และ CommonJS ง่ายขึ้น
"esModuleInterop": true,
// ไม่ตรวจสอบไฟล์ declaration (.d.ts)
"skipLibCheck": true,
// บังคับใช้การตั้งชื่อไฟล์ให้สอดคล้องกัน (case-sensitive)
"forceConsistentCasingInFileNames": true
},
// ไฟล์ที่ต้องการคอมไพล์
"include": ["src"],
// ไฟล์ที่ต้องการยกเว้น
"exclude": ["node_modules"]
}
การกำหนดค่า compilerOptions เป็นหัวใจสำคัญในการตั้งค่า TypeScript
compilerOptions
ตัวเลือก | คำอธิบาย | ประโยชน์ |
---|---|---|
target | เวอร์ชัน JavaScript ที่คอมไพล์ออกมา | เข้ากันได้กับรุ่นเบราว์เซอร์หรือ Node.js ที่ต้องการ |
module | ระบบโมดูลที่ใช้ | กำหนดรูปแบบการนำเข้า/ส่งออกโมดูล |
strict | เปิดโหมดตรวจสอบชนิดแบบเข้มงวดทั้งหมด | ลดข้อผิดพลาดและเพิ่มความปลอดภัยของชนิดข้อมูล |
esModuleInterop | ทำให้การทำงานกับโมดูล ES6 และ CommonJS ง่ายขึ้น | เข้ากันได้ดีกับไลบรารีต่างๆ |
skipLibCheck | ข้ามการตรวจสอบไฟล์ declaration | เพิ่มความเร็วในการคอมไพล์ |
forceConsistentCasingInFileNames | บังคับใช้การตั้งชื่อไฟล์ให้สอดคล้องกัน | ป้องกันปัญหาเรื่อง case sensitivity |
outDir | โฟลเดอร์ที่เก็บไฟล์ที่คอมไพล์แล้ว | จัดการไฟล์ที่คอมไพล์แล้วอย่างเป็นระเบียบ |
rootDir | โฟลเดอร์หลักของโปรเจค | กำหนดโครงสร้างโปรเจคให้ชัดเจน |
baseUrl | ใช้สำหรับกำหนด path mapping | ทำให้การ import สะดวกขึ้น |
paths | กำหนด alias สำหรับ imports | ลดความซับซ้อนของ path ในการ import |
jsx | วิธีการจัดการ JSX | สนับสนุนการพัฒนา React/JSX |
declaration | สร้างไฟล์ .d.ts | ช่วยในการใช้งานไลบรารีกับ TypeScript |
sourceMap | สร้าง source map สำหรับ debugging | เดบักโค้ดต้นฉบับได้แม้ทำงานกับไฟล์ที่คอมไพล์แล้ว |
noImplicitAny | แจ้งเตือนเมื่อมี implicit any | บังคับใช้การระบุชนิดข้อมูลอย่างชัดเจน |
strictNullChecks | ตรวจสอบ null/undefined อย่างเข้มงวด | ลดข้อผิดพลาดจากค่า null/undefined |
allowJs | อนุญาตให้คอมไพล์ไฟล์ JavaScript | ทำให้สามารถใช้งานไฟล์ JavaScript เดิมได้ |
checkJs | ตรวจสอบชนิดในไฟล์ JavaScript | ได้รับประโยชน์จาก TypeScript ในไฟล์ .js |
ดูตัวเลือกทั้งหมดได้ที่ เอกสารทางการ TypeScript
Type System
ระบบชนิดข้อมูล (Type System) เป็นหัวใจสำคัญของ TypeScript ที่ช่วยเพิ่มความปลอดภัยและความชัดเจนให้กับโค้ด โดยระบบชนิดข้อมูลจะทำหน้าที่:
- ตรวจสอบความถูกต้องของชนิดข้อมูลขณะคอมไพล์
- ป้องกันข้อผิดพลาดที่เกิดขึ้นจากการใช้ชนิดข้อมูลผิดประเภท
- ช่วยในการทำเอกสารโค้ดอัตโนมัติ
- เพิ่มประสิทธิภาพเครื่องมือพัฒนาเช่น IntelliSense
Basic Types
ชนิดข้อมูลพื้นฐานที่สำคัญใน TypeScript:
ชนิดข้อมูล | คำอธิบาย | ควรใช้งานเมื่อไหร่ | ตัวอย่างโค้ด |
---|---|---|---|
string | ใช้เก็บข้อความ Unicode | เมื่อต้องเก็บข้อมูลข้อความหรือเนื้อหา | let name: string = 'John' |
number | เก็บได้ทั้งจำนวนเต็มและทศนิยม | เมื่อต้องเก็บข้อมูลตัวเลข | let age: number = 30 |
boolean | ค่าทางตรรกะ true/false | เมื่อต้องตรวจสอบเงื่อนไข | let isActive: boolean = true |
array | อาร์เรย์ของชนิดเดียวกัน | เมื่อต้องจัดการชุดข้อมูล | let nums: number[] = [1, 2, 3] |
tuple | คู่ลำดับที่รู้จักชนิดและจำนวนสมาชิก | เมื่อรู้โครงสร้างข้อมูลที่แน่นอน | let user: [string, number] = ['John', 30] |
typescript
// ตัวอย่างการใช้ string
let name: string = 'John';
typescript
// ตัวอย่างการใช้ number
let age: number = 30;
typescript
// ตัวอย่างการใช้ boolean
let isActive: boolean = true;
typescript
// ตัวอย่างการใช้ array
let nums: number[] = [1, 2, 3];
typescript
// ตัวอย่างการใช้ tuple
let user: [string, number] = ['John', 30];
Special Types
ชนิดข้อมูลพิเศษสำหรับกรณีใช้งานเฉพาะ:
ชนิดข้อมูล | คำอธิบาย | ควรใช้งานเมื่อไหร่ | ตัวอย่างโค้ด |
---|---|---|---|
any | ปิดการตรวจสอบชนิด | เมื่อต้องใช้กับโค้ด JavaScript เดิม | let value: any = 'text' |
unknown | ปลอดภัยกว่า any | เมื่อต้องรับค่าจากแหล่งภายนอก | let value: unknown |
void | ไม่คืนค่า | เมื่อฟังก์ชันไม่คืนค่า | function log(): void {} |
never | ไม่มีค่าที่เป็นไปได้ | เมื่อฟังก์ชัน throw error | function error(): never {} |
enum | กลุ่มค่าคงที่ | เมื่อต้องการชุดค่าที่กำหนดไว้ | enum Color { Red, Green } |
typescript
// ตัวอย่างการใช้ any
let value: any = 'text';
typescript
// ตัวอย่างการใช้ unknown
let value: unknown;
typescript
// ตัวอย่างการใช้ void
function log(): void {
console.log('Hello');
}
typescript
// ตัวอย่างการใช้ never
function error(): never {
throw new Error('Error');
}
typescript
// ตัวอย่างการใช้ enum
enum Color {
Red,
Green
}
Type Composition
เทคนิคการรวมและจัดการชนิดข้อมูล:
ชนิดข้อมูล | คำอธิบาย | ควรใช้งานเมื่อไหร่ | ตัวอย่างโค้ด |
---|---|---|---|
Union | ค่าอาจเป็นได้หลายชนิด | เมื่อต้องรับค่าหลายชนิด | `let id: string |
Intersection | รวม properties | เมื่อต้องขยาย interface | type AdminUser = User & Admin |
typescript
// ตัวอย่างการใช้ union
let userId: string | number;
typescript
// ตัวอย่างการใช้ intersection
interface User { name: string; }
interface Admin { roles: string[]; }
type AdminUser = User & Admin;
const adminUser: AdminUser = {
name: 'John Doe',
roles: ['admin', 'moderator']
};
Type Creation
การสร้างชนิดข้อมูลใหม่:
ชนิดข้อมูล | คำอธิบาย | ควรใช้งานเมื่อไหร่ | ตัวอย่างโค้ด |
---|---|---|---|
interface | กำหนดโครงสร้างอ็อบเจ็กต์ | เมื่อต้องการขยายได้ | interface User { name: string } |
type alias | กำหนดชื่อให้ชนิดข้อมูล | เมื่อต้องการ union/intersection | type Point = { x: number, y: number } |
typescript
// ตัวอย่างการใช้ Interface
interface User {
name: string;
age: number;
email?: string; // optional property
}
const user: User = {
name: 'John',
age: 30
};
typescript
// ตัวอย่างการใช้ Type Alias
type Point = {
x: number;
y: number;
};
const center: Point = {
x: 0,
y: 0
};
Utility Types
ชนิดข้อมูลที่ช่วยจัดการและแปลงชนิดข้อมูล:
ชนิดข้อมูล | คำอธิบาย | ควรใช้งานเมื่อไหร่ | ตัวอย่างโค้ด |
---|---|---|---|
Partial<T> | ทำให้ทุก property เป็น optional | เมื่อต้องการส่งบาง properties | Partial<User> |
Readonly<T> | ทำให้ทุก property เป็น readonly | เมื่อต้องการป้องกันการแก้ไข | Readonly<User> |
Pick<T,K> | เลือกบาง properties | เมื่อต้องการส่วนย่อยของ type | Pick<User, 'name'> |
Omit<T,K> | ละเว้นบาง properties | เมื่อต้องการยกเว้นบาง field | Omit<User, 'id'> |
typescript
// ทำให้ทุก property เป็น optional
interface Product {
id: string;
name: string;
price: number;
}
const partialProduct: Partial<Product> = {
name: 'Laptop' // สามารถใส่เฉพาะบาง properties ได้
};
typescript
// ทำให้ทุก property เป็น readonly
const readOnlyUser: Readonly<User> = {
name: 'Jane',
age: 25
};
// readOnlyUser.name = 'John'; // Error: Cannot assign to 'name' because it is a read-only property
typescript
// เลือกบาง properties
type UserName = Pick<User, 'name'>;
const userName: UserName = {
name: 'Mike'
};
typescript
// ละเว้นบาง properties
type UserWithoutAge = Omit<User, 'age'>;
const userWithoutAge: UserWithoutAge = {
name: 'Sarah'
};
Practical Examples
ฟีเจอร์ | คำอธิบาย | ตัวอย่างการใช้งาน |
---|---|---|
Union Types | TypeA | TypeB - รับค่าหลายชนิด | ใช้งานเมื่อต้องการรับค่าที่เป็นได้หลายประเภท เช่น ID ที่อาจเป็น string หรือ number |
Intersection Types | TypeA & TypeB - รวม properties จากหลาย type | สร้าง type ใหม่จาก interface ที่มีอยู่ |
Type Guards | ตรวจสอบชนิดข้อมูลขณะรัน | ใช้งานกับ union types อย่างปลอดภัย |
Utility Types | Type ที่มีอยู่แล้วสำหรับแปลง type อื่น | สร้าง type ที่ดัดแปลงมาจาก type อื่นอย่างรวดเร็ว |
Generics | พารามิเตอร์ type ที่นำกลับมาใช้ได้ | สร้าง component ที่ยืดหยุ่นและปลอดภัยทางชนิดข้อมูล |
Decorators | เพิ่มเติมพฤติกรรมให้ class/method | Logging, Validation, Dependency Injection |
Mapped Types | สร้าง type โดยการ map properties | สร้าง type ใหม่จาก existing type |
Conditional Types | type ที่ขึ้นอยู่กับเงื่อนไข | กรอง type ตามเงื่อนไขที่กำหนด |
ส่วนนี้แสดงตัวอย่างการใช้งาน TypeScript ในสถานการณ์จริง พร้อมคำอธิบายใน comment เพื่อความเข้าใจที่ชัดเจน
Type Manipulation
การจัดการชนิดข้อมูลด้วย Union และ Intersection Types Union Types ใช้เมื่อค่าอาจเป็นได้หลายชนิด Intersection Types ใช้เมื่อต้องการรวม properties จากหลาย interface เข้าด้วยกัน
typescript
// Union Type: Accepts either string or number
let userId: string | number;
userId = 'USER123'; // Valid
userId = 1001; // Valid
// Intersection Type: Combines properties from multiple interfaces
interface User { name: string; }
interface Admin { roles: string[]; }
type AdminUser = User & Admin;
// ตัวอย่างการใช้งาน AdminUser
let adminUser: AdminUser = {
name: 'John Doe',
roles: ['admin', 'moderator']
};
Type Guards
เทคนิคการตรวจสอบชนิดข้อมูลก่อนใช้งาน ช่วยให้ TypeScript สามารถ推断ชนิดข้อมูลได้อย่างถูกต้อง สามารถใช้ typeof, instanceof หรือ user-defined type guards
typescript
// ตรวจสอบชนิดข้อมูลก่อนใช้งาน
function processValue(val: string | number) {
if (typeof val === 'string') {
// TypeScript รู้ว่า val เป็น string ในบล็อกนี้
return val.toUpperCase();
}
// TypeScript รู้ว่า val เป็น number ในบล็อกนี้
return val.toFixed(2);
}
Utility Types
Built-in types ที่ช่วยจัดการและแปลงชนิดข้อมูล ช่วยลดการเขียนโค้ดซ้ำซ้อน มีประโยชน์ในการสร้าง type ที่มีโครงสร้างเฉพาะ
typescript
// ตัวอย่างการใช้ Utility Types
interface Product {
id: number;
name: string;
price: number;
inStock: boolean;
}
// สร้าง type ที่มีบาง properties เท่านั้น
type ProductPreview = Pick<Product, 'id' | 'name'>;
// สร้าง type ที่ไม่มีบาง properties
type ProductWithoutPrice = Omit<Product, 'price'>;
Generics
การสร้าง component ที่ทำงานกับหลายชนิดข้อมูล เพิ่มความยืดหยุ่นในการใช้งาน ยังคงความปลอดภัยของชนิดข้อมูล
typescript
// ฟังก์ชัน generics ที่ทำงานกับหลายชนิดข้อมูล
function identity<T>(arg: T): T {
return arg;
}
// เรียกใช้งาน
const output1 = identity<string>('hello');
const output2 = identity<number>(42);
Decorators
typescript
function log(target: any, key: string) {
console.log(`Method ${key} called`);
}
class Calculator {
@log
add(a: number, b: number) {
return a + b;
}
}
Mapped Types
typescript
type Optional<T> = {
[P in keyof T]?: T[P];
};
interface User {
name: string;
age: number;
}
type OptionalUser = Optional<User>;
Conditional Types
typescript
type NonNullable<T> = T extends null | undefined ? never : T;
type ValidString = NonNullable<string | null>; // ผลลัพธ์คือ string