DEV Community

Cover image for จาก JavaScript ไปยัง TypeScript เริ่มยังไง
Somprasong Damyos
Somprasong Damyos

Posted on

จาก JavaScript ไปยัง TypeScript เริ่มยังไง

โดยปกติผมจะเขียนโค้ดอยู่คนเดียว ความ dynamic type ของ JavaScript ก็ไม่ได้สร้างปัญหา สร้าง bug ให้กับผม แต่เนื่องจาก ต้องการจะลองใช้งาน Nestjs ซึเขียนด้วย TypeScript จึงบันทึกเอาไว้สักหน่อยว่าจะเปลี่ยนจาก JavaScript ไปยัง TypeScript นั้นต้องทำยังไงบ้าง

Prerequisites

  1. มีความเข้าใจภาษา JavaScript ระดับหนึ่ง
  2. ตั้งค่าโปรเจคเพิ่มเขียน TypeScript จาก ที่นี่

TypeScript คืออะไร 🤔

ซึ่งถ้าถามว่า TypeScript คืออะไร ผมคงตอบไปสั้นๆ ว่า คือการเอา static type มาใส่เข้าไปใน JavaScript นั่นเอง
ลองดูตัวอย่างนี้ เช่น มี function สำหรับเพิ่มค่าตัวเลข ถ้าเป็น Javascript เราจำเป็นที่จะต้องตรวจสอบ type ก่อน เพื่อป้องกันการเกิด error

// app.js
let counter = 10;

function increateCounter() {
  if (typeof counter === 'number') {
    counter += 1;
  } else {
    throw new Error('counter is not a number');
  }
}
Enter fullscreen mode Exit fullscreen mode

แต่ถ้าใช้ TypeScript เราไม่ต้องตรวจสอบ type เองแล้ว

let counter: number = 10;

function increateCounter() {
  counter += 1;
}
Enter fullscreen mode Exit fullscreen mode

ชีวิตดูดีขึ้นเยอะ 👍

มาทำความรู้จัก Type กันก่อน 😏

มาลองดูกันว่า TypeScript มีชนิดข้อมูลแบบไหนบ้าง

1. Predefined Types

เป็นชนิดของข้อมูลที่ถูกเตรียมไว้ให้แล้ว โดยขอเริ่มจของ JavaScript ซึ่งที่ใช้งานบ่อยๆ นั้นก็จะมีประมาณนี้

  • String
  • Number
  • Boolean
  • Array
  • Function
  • Object

และส่วนที่เพิ่มเข้ามาจาก TypeScript มีดังนี้

  • Any - ถ้าไม่รู้จะใส่ type อะไร ให้ใส่ตัวนี้ไปเลย และมันก็จะไปปิดการทำ type checking
  • Tuple - คือ Array ที่ต้องระบุขนาดตายตัว และต้องกำหนดกำหนดชนิดข้อมูลให้แต่ละ elements ด้วย เช่น
let rgbColor = [number, number, number];
Enter fullscreen mode Exit fullscreen mode
  • Enum - ใช้กำหนดชื่อให้กับค่าชุดหนึ่งได้ โดยค่าจะเริ่มจาก 0 เช่น
enum ArrowKeys {
  Up, // 0
  Down, // 1
  Left, // 2
  Right, // 3
}
// หรือจะกำหนดค่าเองก็ได้
enum ArrowKeys {
  Up = 'up',
  Down = 'down',
  Left = 'left',
  Right = 'right',
}
Enter fullscreen mode Exit fullscreen mode

ยังมีอีกหลาย type แต่เอาเท่าที่ใช้งานบ่อยๆ ก่อน

วิธีกำหนดชนิดข้อมูลให้กับตัวแปร

ิวิธีกำหนดนั้นง่ายมาก เพียงแค่ใส่ :type หลังชื่อตัวแปรก็ได้แล้ว

  • เริ่มจากชนิดข้อมูลพื้นฐานก่อน String, Number และ Boolean
// javascript
let name = 'Stamp';
let age = 5;
let isSterilized = true;
Enter fullscreen mode Exit fullscreen mode

เมื่อเขียนแบบ TypeScript

// typescript
let name: string = 'Stamp';
let age: number = 5;
let isSterilized: boolean = true;
Enter fullscreen mode Exit fullscreen mode
  • Array บอกไว้ก่อนไม่ได้ใช้ :array นะ 😆
// javascript
let favoriteFoods = ['Chicken', 'Corn', 'Strawberry'];
Enter fullscreen mode Exit fullscreen mode

เมื่อเขียนแบบ TypeScript ให้ดูว่าข้อมูลใน array เป็นอะไร ก็ใช้ type แล้วตาม []

// typescript
let favoriteFoods: string[] = ['Chicken', 'Corn', 'Strawberry'];
Enter fullscreen mode Exit fullscreen mode
  • Function จะมีกำหนดอยู่ 2 ส่วน คือ 1. ตรง parameter และ 2. ค่าที่ต้อง return กลับไป
// javascript
let generateFullName = (firstName, lastName) => {
  return firstName + ' ' + lastName;
};
Enter fullscreen mode Exit fullscreen mode

เมื่อเขียนแบบ TypeScript

// typescript
let generateFullName = (firstName: string, lastName: string): string => {
  return firstName + ' ' + lastName;
};
Enter fullscreen mode Exit fullscreen mode
  • Object
// javascript
let dog = {
  name: 'Stamp',
  age: 5,
  gender: 'male',
  isSterilized: true,
  favoriteFoods: ['Chicken', 'Corn', 'Strawberry'],
};
Enter fullscreen mode Exit fullscreen mode

เมื่อเขียนแบบ TypeScript ก็กำหนดลงไปตรงๆ หลังชื่อตัวแปรได้เลย (ใช้ ; นะ)

// typescript
let dog: {
  name: string;
  age: number;
  gender: string;
  isSterilized: boolean;
  favoriteFoods: string[];
} = {
  name: 'Stamp',
  age: 5,
  gender: 'male',
  isSterilized: true,
  favoriteFoods: ['Chicken', 'Corn', 'Strawberry'],
};
Enter fullscreen mode Exit fullscreen mode

2.Custom Type

จากการกำหนด type ของ object แบบข้างบนนั้น ถ้าเรามี dog2 ก็ต้องมากำหนด type แบบนี้ซ้ำขึ้น ทำให้ขาดความ reuseable ไปดังนั้นเราจำเป็นที่จะต้องสร้าง custom type ขึ้นมาเอง โดยการใช้ type และ interface

แล้ว type คืออะไร 🤨

type นั้นเป็นการสร้าง alias type ขึ้นมาเพื่อบอกว่า type นั้นๆ ควรมีหน้าตาเป็นยังไง เช่น gender นั้นสามารถระบุได้แค่ male กับ female เท่านั้น เราก็สามารถสร้างเป็น genderType ขึ้นมาได้เพื่อให้ระบุได้เฉพาะ สองค่านี้เท่านั้น ทำได้โดย

type genderType = 'male';

let gender: genderType = 'male';
Enter fullscreen mode Exit fullscreen mode

แต่ถ้าลองกำหนด let gender: genderType = 'female'; แบบนี้จะยังทำไม่ได้ เราจะต้องใช้ Union Operater มาช่วยในการสร้าง type ให้สมบูรณ์

type genderType = 'male' | 'female';

let gender: genderType = 'female';
Enter fullscreen mode Exit fullscreen mode

แล้ว interface มีไว้ทำไม😅

เจ้า interface นี่คือเอาไว้กำหนดหว่า Object นั้นๆ จะมีหน้าตาเป็นยังไง

โดยจะเอาตัวอย่างข้างบน มาสร้าง interface ดู

// typescript
interface Dog {
  name: string;
  age: number;
  gender: string;
  isSterilized: boolean;
  favoriteFoods: string[];
}

let dog: Dog = {
  name: 'Stamp',
  age: 5,
  gender: 'male',
  isSterilized: true,
  favoriteFoods: ['Chicken', 'Corn', 'Strawberry'],
};
Enter fullscreen mode Exit fullscreen mode

และเรายังสามารถใช้ type และ interface ร่วมกันได้ แบบนี้

// typescript
type genderType = 'male' | 'female';

interface Dog {
  name: string;
  age: number;
  gender: genderType;
  isSterilized: boolean;
  favoriteFoods: string[];
}

let dog: Dog = {
  name: 'Stamp',
  age: 5,
  gender: 'male',
  isSterilized: true,
  favoriteFoods: ['Chicken', 'Corn', 'Strawberry'],
};
Enter fullscreen mode Exit fullscreen mode

คร่าวนี้ก็วามารถ reuse การสร้าง Object ของ dog ได้แล้ว 🎉

3. Type Assertion

ในบางกรณีเราอาจสร้าง object เปล่าแบบนี้ let dog = {}; ซึ่ง TypeScript จะไม่รู้จักว่า Object นี่คือ type อะไร มี property อะไรบ้าง

let dog = {};
dog.name = 'Snow'; // Property 'name' does not exist on type '{}'.
Enter fullscreen mode Exit fullscreen mode

ทำให้เราไม่สามารถกำหนดค่า property ให้กับ dog ได้ เพราะ TypeScript ไม่รู้จัก

แต่สามารถแก้ได้โดยการใช้ as ดังนี้

let dog = {} as Dog; // ใช้ as เพื่อบอกชนิดของ object
dog.name = 'Snow';
dog.age = 5;
dog.gender = 'female';
dog.isSterilized = true;
dog.favoriteFoods = ['Chicken', 'Corn', 'Strawberry'];
Enter fullscreen mode Exit fullscreen mode

แบบนี้ TypeScript ก็รู้แล้วว่าเป็น Dog

4. Generic Type

มาถึงตัวสุดท้ายของบทความนี้แล้ว

งั้นขออธิบายจากโค้ดเลยละกัน

ตัวอย่างเช่น มีฟังก์ชัน createNumberList และ createStringList

function createNumberList(item: number): number[] {
  const newList: number[] = [];

  newList.push(item);

  return newList;
}

function createStringList(item: string): string[] {
  const newList: string[] = [];

  newList.push(item);

  return newList;
}

const numberList = createNumberList(123);
const stringList = createNumberList('abc');
Enter fullscreen mode Exit fullscreen mode

จะเห็นว่าทั้ง 2 ฟังก์ชันนั้นทำงานเหมือนกันเลย แต่ต่างกันแค่ชนิดของข้อมูล เราจะทำยังไงให้มัน reuseable ได้ โดยให้เหลือแค่ฟังก์ชัน createList เท่านั้น

ในการทำแบบนี้เราจะใช้ Generic Type เข้ามาช่วย แบบนี้

function createList<CustomType>(item: CustomType): CustomType[] {
  const newList: CustomType[] = [];

  newList.push(item);

  return newList;
}

const numberList = createList<number>(123);
const stringList = createList<string>('abc');
Enter fullscreen mode Exit fullscreen mode

ตรงคำว่า CustomType นั่นด็คือ Generic จริงๆ แล้วจะใช้ชื่ออะไรก็ได้ แต่โดยทั่วไปจะใช้ตัว T กัน แบบนี้

function createList<T>(item: T): T[] {
  const newList: T[] = [];

  newList.push(item);

  return newList;
}

const numberList = createList<number>(123);
const stringList = createList<string>('abc');
Enter fullscreen mode Exit fullscreen mode

ซึ่งจะเห็นว่าการใช้งาน Generic Type นั้นจะช่วยให้โค้ดของเราสามารถ reuseable ได้แล้ว


จริงๆ แล้ว TypeScript นั้นยังมีเนื้อหาอีกเยอะ แต่คิดว่าเมื่อเข้าใจเรื่อง Type ในบทความนี้ดีแล้ว ก็น่าจะเริ่มเขียน TypeScript ได้แล้วหล่ะครับ ^^

Top comments (0)