Skip to content

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:

  1. เขียนโค้ด TypeScript (.ts)
  2. Type Checker ตรวจสอบชนิดข้อมูล
  3. หากถูกต้อง จะคอมไพล์เป็น JavaScript (.js)
  4. หากมีข้อผิดพลาด จะแสดง Error Messages
  5. โค้ด 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:

package.json
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"
  }
}

หรือสร้างไฟล์ด้วยคอนฟิกพื้นฐาน:

tsconfig.json
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

ตัวเลือกคำอธิบายประโยชน์
www.typescriptlang.org favicontargetเวอร์ชัน JavaScript ที่คอมไพล์ออกมาเข้ากันได้กับรุ่นเบราว์เซอร์หรือ Node.js ที่ต้องการ
www.typescriptlang.org faviconmoduleระบบโมดูลที่ใช้กำหนดรูปแบบการนำเข้า/ส่งออกโมดูล
www.typescriptlang.org faviconstrictเปิดโหมดตรวจสอบชนิดแบบเข้มงวดทั้งหมดลดข้อผิดพลาดและเพิ่มความปลอดภัยของชนิดข้อมูล
www.typescriptlang.org faviconesModuleInteropทำให้การทำงานกับโมดูล ES6 และ CommonJS ง่ายขึ้นเข้ากันได้ดีกับไลบรารีต่างๆ
www.typescriptlang.org faviconskipLibCheckข้ามการตรวจสอบไฟล์ declarationเพิ่มความเร็วในการคอมไพล์
www.typescriptlang.org faviconforceConsistentCasingInFileNamesบังคับใช้การตั้งชื่อไฟล์ให้สอดคล้องกันป้องกันปัญหาเรื่อง case sensitivity
www.typescriptlang.org faviconoutDirโฟลเดอร์ที่เก็บไฟล์ที่คอมไพล์แล้วจัดการไฟล์ที่คอมไพล์แล้วอย่างเป็นระเบียบ
www.typescriptlang.org faviconrootDirโฟลเดอร์หลักของโปรเจคกำหนดโครงสร้างโปรเจคให้ชัดเจน
www.typescriptlang.org faviconbaseUrlใช้สำหรับกำหนด path mappingทำให้การ import สะดวกขึ้น
www.typescriptlang.org faviconpathsกำหนด alias สำหรับ importsลดความซับซ้อนของ path ในการ import
www.typescriptlang.org faviconjsxวิธีการจัดการ JSXสนับสนุนการพัฒนา React/JSX
www.typescriptlang.org favicondeclarationสร้างไฟล์ .d.tsช่วยในการใช้งานไลบรารีกับ TypeScript
www.typescriptlang.org faviconsourceMapสร้าง source map สำหรับ debuggingเดบักโค้ดต้นฉบับได้แม้ทำงานกับไฟล์ที่คอมไพล์แล้ว
www.typescriptlang.org faviconnoImplicitAnyแจ้งเตือนเมื่อมี implicit anyบังคับใช้การระบุชนิดข้อมูลอย่างชัดเจน
www.typescriptlang.org faviconstrictNullChecksตรวจสอบ null/undefined อย่างเข้มงวดลดข้อผิดพลาดจากค่า null/undefined
www.typescriptlang.org faviconallowJsอนุญาตให้คอมไพล์ไฟล์ JavaScriptทำให้สามารถใช้งานไฟล์ JavaScript เดิมได้
www.typescriptlang.org faviconcheckJsตรวจสอบชนิดในไฟล์ JavaScriptได้รับประโยชน์จาก TypeScript ในไฟล์ .js

ดูตัวเลือกทั้งหมดได้ที่ www.typescriptlang.org faviconเอกสารทางการ 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 errorfunction 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เมื่อต้องขยาย interfacetype 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/intersectiontype 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เมื่อต้องการส่งบาง propertiesPartial<User>
Readonly<T>ทำให้ทุก property เป็น readonlyเมื่อต้องการป้องกันการแก้ไขReadonly<User>
Pick<T,K>เลือกบาง propertiesเมื่อต้องการส่วนย่อยของ typePick<User, 'name'>
Omit<T,K>ละเว้นบาง propertiesเมื่อต้องการยกเว้นบาง fieldOmit<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 TypesTypeA | TypeB - รับค่าหลายชนิดใช้งานเมื่อต้องการรับค่าที่เป็นได้หลายประเภท เช่น ID ที่อาจเป็น string หรือ number
Intersection TypesTypeA & TypeB - รวม properties จากหลาย typeสร้าง type ใหม่จาก interface ที่มีอยู่
Type Guardsตรวจสอบชนิดข้อมูลขณะรันใช้งานกับ union types อย่างปลอดภัย
Utility TypesType ที่มีอยู่แล้วสำหรับแปลง type อื่นสร้าง type ที่ดัดแปลงมาจาก type อื่นอย่างรวดเร็ว
Genericsพารามิเตอร์ type ที่นำกลับมาใช้ได้สร้าง component ที่ยืดหยุ่นและปลอดภัยทางชนิดข้อมูล
Decoratorsเพิ่มเติมพฤติกรรมให้ class/methodLogging, Validation, Dependency Injection
Mapped Typesสร้าง type โดยการ map propertiesสร้าง type ใหม่จาก existing type
Conditional Typestype ที่ขึ้นอยู่กับเงื่อนไขกรอง 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

Last updated: