โดยปกติผมจะเขียนโค้ดอยู่คนเดียว ความ dynamic type ของ JavaScript ก็ไม่ได้สร้างปัญหา สร้าง bug ให้กับผม แต่เนื่องจาก ต้องการจะลองใช้งาน Nestjs ซึเขียนด้วย TypeScript จึงบันทึกเอาไว้สักหน่อยว่าจะเปลี่ยนจาก JavaScript ไปยัง TypeScript นั้นต้องทำยังไงบ้าง
Prerequisites
- มีความเข้าใจภาษา JavaScript ระดับหนึ่ง
- ตั้งค่าโปรเจคเพิ่มเขียน 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'); } }
แต่ถ้าใช้ TypeScript เราไม่ต้องตรวจสอบ type เองแล้ว
let counter: number = 10; function increateCounter() { counter += 1; }
ชีวิตดูดีขึ้นเยอะ 👍
มาทำความรู้จัก 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];
- Enum - ใช้กำหนดชื่อให้กับค่าชุดหนึ่งได้ โดยค่าจะเริ่มจาก 0 เช่น
enum ArrowKeys { Up, // 0 Down, // 1 Left, // 2 Right, // 3 } // หรือจะกำหนดค่าเองก็ได้ enum ArrowKeys { Up = 'up', Down = 'down', Left = 'left', Right = 'right', }
ยังมีอีกหลาย type แต่เอาเท่าที่ใช้งานบ่อยๆ ก่อน
วิธีกำหนดชนิดข้อมูลให้กับตัวแปร
ิวิธีกำหนดนั้นง่ายมาก เพียงแค่ใส่ :type
หลังชื่อตัวแปรก็ได้แล้ว
- เริ่มจากชนิดข้อมูลพื้นฐานก่อน String, Number และ Boolean
// javascript let name = 'Stamp'; let age = 5; let isSterilized = true;
เมื่อเขียนแบบ TypeScript
// typescript let name: string = 'Stamp'; let age: number = 5; let isSterilized: boolean = true;
- Array บอกไว้ก่อนไม่ได้ใช้
:array
นะ 😆
// javascript let favoriteFoods = ['Chicken', 'Corn', 'Strawberry'];
เมื่อเขียนแบบ TypeScript ให้ดูว่าข้อมูลใน array เป็นอะไร ก็ใช้ type แล้วตาม []
// typescript let favoriteFoods: string[] = ['Chicken', 'Corn', 'Strawberry'];
- Function จะมีกำหนดอยู่ 2 ส่วน คือ 1. ตรง parameter และ 2. ค่าที่ต้อง return กลับไป
// javascript let generateFullName = (firstName, lastName) => { return firstName + ' ' + lastName; };
เมื่อเขียนแบบ TypeScript
// typescript let generateFullName = (firstName: string, lastName: string): string => { return firstName + ' ' + lastName; };
- Object
// javascript let dog = { name: 'Stamp', age: 5, gender: 'male', isSterilized: true, favoriteFoods: ['Chicken', 'Corn', 'Strawberry'], };
เมื่อเขียนแบบ 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'], };
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';
แต่ถ้าลองกำหนด let gender: genderType = 'female';
แบบนี้จะยังทำไม่ได้ เราจะต้องใช้ Union Operater มาช่วยในการสร้าง type ให้สมบูรณ์
type genderType = 'male' | 'female'; let gender: genderType = 'female';
แล้ว 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'], };
และเรายังสามารถใช้ 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'], };
คร่าวนี้ก็วามารถ 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 '{}'.
ทำให้เราไม่สามารถกำหนดค่า 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'];
แบบนี้ 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');
จะเห็นว่าทั้ง 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');
ตรงคำว่า 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');
ซึ่งจะเห็นว่าการใช้งาน Generic Type นั้นจะช่วยให้โค้ดของเราสามารถ reuseable ได้แล้ว
จริงๆ แล้ว TypeScript นั้นยังมีเนื้อหาอีกเยอะ แต่คิดว่าเมื่อเข้าใจเรื่อง Type ในบทความนี้ดีแล้ว ก็น่าจะเริ่มเขียน TypeScript ได้แล้วหล่ะครับ ^^
Top comments (0)