[TypeScript#1] TypeScript คืออะไร? เรียนรู้ชนิดข้อมูลพื้นฐานของ TypeScript

Nuttavut Thongjor

TypeScript เป็นอีกหนึ่งภาษาทางเลือกที่มาแรงช่วงนี้ ด้วยความที่ Angular2 นั้นสนับสนุนการใช้งานกับ TypeScript อย่างสมบูรณ์จึงไม่แปลกที่ชุมชนนักพัฒนาจะให้ความสนใจ ไม่ใช่สำหรับ Angular2 เท่านั้นแต่หลายโปรเจคในโลกของ React ก็มีการขยับไปใช้ TypeScript แทน FlowType ในบทความนี้เราจะมาลองกันครับว่า TypeScript ดีจริงหรือแค่ราคาคุย!

ก่อนที่เพื่อนๆจะอ่านบทความนี้ ผมอยากแนะนำให้เพื่อนๆอ่านบทความ พื้นฐาน ES2015 (ES6) สำหรับการเขียน JavaScript สมัยใหม่ ก่อนครับ นั่นเป็นเพราะโค๊ด JavaScript ก็ถือว่าเป็นโค๊ด TypeScript เช่นเดียวกัน

TypeScript คืออะไร

TypeScript เป็นภาษาโปรแกรมที่รวมความสามารถที่ ES2015 เองมีอยู่ สิ่งที่เพิ่มขึ้นมาคือสนับสนุน Type System รวมถึงคุณสมบัติอื่นๆที่เพิ่มมากขึ้น เช่น Enum และความสามารถที่เพิ่มขึ้นของการโปรแกรมเชิงวัตถุ TypeScript นั้นเป็น transpiler เหมือน Babel นั่นหมายความว่าตัวแปลภาษาของ TypeScript จะแปลโค๊ดที่เราเขียนให้เป็น JavaScript อีกทีนึง จึงมั่นใจได้ว่าผลลัพธ์สุดท้ายจะสามารถใช้งานได้บนเว็บเบราเซอร์ทั่วไป

ข้อดีของการใช้ TypeScript

  • TypeScript ทำให้คุณใช้ JavaScript สมัยใหม่ได้ในปัจจุบัน ความสามารถของ ES2015 และอื่นๆ ได้รวมไว้แล้วใน TypeScript
  • ตัวแปรที่คุณประกาศแล้วใน TypeScript จะเปลี่ยนชนิดข้อมูลไม่ได้อีกต่อไป ข้อผิดพลาดในโปรแกรมคุณจะน้อยลงเพราะคุณไม่มีโอกาสพลาดในการใส่ข้อมูลผิดชนิดเป็นแน่
  • TypeScript มีการตรวจสอบโค๊ดในช่วง compile time ทำให้คุณดักจับข้อผิดพลาดได้แต่ต้นไม่ปล่อยให้ข้อผิดพลาดไปโผล่ในตอนทำงานจริง (runtime)
  • IDE และ Text Editor ที่ดีเยี่ยมสนับสนุนให้คุณใช้งาน TypeScript ได้อย่างสมบูรณ์

ข้อควรรู้ทั่วไปเกี่ยวกับ TypeScript

  • โค๊ด JavaScript ธรรมดาก็คือโค๊ด TypeScript ด้วยเช่นกัน
  • เราสามารถระบุหรือไม่ระบุชนิดข้อมูลใน TypeScript ก็ได้ แต่เมื่อประกาศตัวแปรแล้วเราจะเปลี่ยนชนิดข้อมูลไม่ได้
TypeScript
1let foo: number = 123
2
3foo = 'Hello ชาวโลก!' Error: cannot assign a `string` to a `number`
  • แม้เราจะใส่ค่าตัวแปรผิดชนิดข้อมูลใน TypeScript แต่ TypeScript ก็ยังใจดีแปลงโค๊ดเป็น JavaScript ให้อยู่ดี
TypeScript
1var foo = 123
2foo = '456' // Error: cannot assign a `string` to a `number`
3
4// ยังคงแปลงเป็น JavaScript แบบนี้
5var foo = 123
6foo = '456'

ชนิดข้อมูลพื้นฐานใน TypeScript

ชนิดข้อมูลพื้นฐานเหล่านี้ใน JavaScript ก็เป็นชนิดข้อมูลใน TypeScript ด้วย ได้แก่ Boolean, Number และ String โดยเราสามารถกำกับชนิดข้อมูลให้ตัวแปรได้ด้วยการระบุชนิดข้อมูลที่ต้องการ ทั้งนี้เราสามารถละชนิดข้อมูลในการประกาศตัวแปรได้เช่นกัน TypeScript จะอนุมานชนิดข้อมูลจากค่าข้อมูลที่เราระบุ ข้อควรจำคือใน TypeScript เมื่อเลือกชนิดข้อมูลให้กับตัวแปรแล้ว เราจะเปลี่ยนชนิดข้อมูลของตัวแปรไม่ได้อีกเลย ตายไปสิบชาติก็ทำไม่ได้ เชื่อเหอะ!

TypeScript
1// ชนิดข้อมูลประเภท Boolean
2let isEmpty: boolean = true
3
4// ชนิดข้อมูลประเภทตัวเลข ไม่ได้จำกัดแค่เลขฐานสิบ
5let decimal: number = 10
6let hex: number = 0xf11a
7
8// ชนิดข้อมูลประเภทข้อความ
9let greeting: string = 'Hello World'

ชนิดข้อมูลประเภท Array, Tuple และ Enum

เมื่อเราต้องการสร้างข้อมูลชุด เราสามารถใช้อาร์เรย์เพื่อสื่อความถึงก้อนข้อมูลนั้น ใน TypeScript เราสามารถระบุชนิดข้อมูลว่าเป็นอาร์เรย์ได้ด้วยสองวิธีต่อจากนี้

  1. ใส่ [] ตามหลังชนิดข้อมูลที่เราต้องการสร้าง เช่น
TypeScript
1let nums: number[] = [1, 2, 3]
  1. ระบุ Array<ชนิดข้อมูล> เช่น
TypeScript
1let nums: Array<number> = [1, 2, 3]

จุดน่าสังเกตคือ เมื่อเราระบุชนิดข้อมูลใดลงไป ทุกๆข้อมูลในอาร์เรย์ต้องเป็นชนิดข้อมูลนั้น เช่น สำหรับ Array<number> ทุกๆอีลีเมนต์ในอาร์เรย์จะต้องเป็นตัวเลขเท่านั้น

แล้วถ้าเรามีอาร์เรย์ที่มีจำนวนข้อมูลจำกัดหละ แล้วเราต้องการให้แต่ละช่องของข้อมูลมีชนิดข้อมูลตามที่เราต้องการ เช่น เราต้องการสร้างอาร์เรย์สองช่อง ช่องแรกเก็บชื่อนักศึกษาและช่องสุดท้ายเก็บคะแนนสอบ โดยชื่อนักศึกษาต้องเป็น string และคะแนนสอบต้องเป็น number จะทำยังไงดีครับ? นั่นละฮะ Tuple คือคำตอบสำหรับคุณ

TypeScript
1// เรานิยามว่า studentAndScore คือ Tuple
2// หรือเป็นอาร์เรย์ที่มีข้อมูลจำกัด
3// พร้อมทั้งผูกชนิดข้อมูลให้แต่ละอีลีเมนต์ของมัน
4let studentAndScore: [string, number]
5
6// หลังจากประกาศตัวแปรแล้วก็โยนค่าใส่ซะ
7studentAndScore = ['Somchai', 77]
8
9// แน่นอนว่าแบบนี้ error เพราะชนิดข้อมูลไม่ตรงกัน
10studentAndScore = [77, 'Somchai']

ตอนนี้่เราต้องการสร้างตัวแปรแทนสีของสัญญาณไฟจราจรที่มีสามสี ถ้าเราบอกว่าให้เลข 1 แทนสีแดง เลข 2 แทนสีเหลือง สุดท้ายเลข 3 แทนสีเขียว แบบนี้เมื่อเรากลับมาอ่านโค๊ด เจอแต่ตัวเลขก็จะงงกันไปสามตลบว่าเห้ยเลขนี้แทนสีอะไร จริงไหมครับ? Enum จะเข้ามาช่วยแก้ปัญหาในจุดนี้

Enum ช่วยให้เรานิยามข้อความขึ้นมาแทนตัวเลขต่างๆได้ ดังนี้

TypeScript
1// ประกาศ Enum ขึ้นมาชื่อ TrafficLight
2enum TrafficLight {
3 // ปกติ Enum จะเริ่มต้นที่เลข 0
4 // ถ้าเราไม่ทำอะไรซักอย่างจะได้ว่า Red มีค่าเป็น 0, Amber = 1 และ Green = 2
5 // แต่เราต้องการให้ Red มีค่าเป็น 1 จึงกำหนดแบบนี้
6 // มีผลทำให้ Red มีค่าเป็น 1, Amber = 2 และ Green = 3
7 Red = 1,
8 Amber,
9 Green,
10}
11
12// สัญญาณไฟปัจจุบันมีค่าเป็น 3 หรือ Green
13// เมื่อใช้ Enum จะทำให้โค๊ดเราอ่านง่ายขึ้น โดยไม่ต้องสนใจว่าตัวเลขไหนแทนค่าอะไร
14let currentSignal = TrafficLight.Green

ชนิดข้อมูลประเภท Any และ Void

จากหัวข้อก่อนหน้านี้ ถ้าผมบอกว่าถ้าอาร์เรย์มีชนิดข้อมูลเป็น Array<number> แล้วทุกๆอีลีเมนต์ในอาร์เรย์นี้ต้องเป็นตัวเลข แต่ถ้าเราต้องการให้อีลีเมนต์ในอาร์เรย์ของเราเป็นชนิดข้อมูลอะไรก็ได้หละ? Any มีคำตอบให้คุณครับ

สวัสดีเราชื่อ Any เอง... เราเป็นคนไม่เรื่องมาก ใครจะจับเราโยน จะปู้ยี้ปู้ยำเราให้เป็นชนิดข้อมูลอะไรก็ได้... เราบอบบางนะ ดูแลเราด้วย...

นั่นหละครับ Any มันสามารถแทนชนิดข้อมูลอะไรก็ได้ ประโยชน์ของมันจึงเป็นดังนี้

  • ถ้าเราไม่แน่ใจว่าข้อมูลของเราจะเป็นชนิดอะไรจึงใช้ Any
  • เราย้ายโค๊ดมาจากโปรเจคเก่า เพื่อให้โปรเจคทำงานได้โดยแก้น้อยที่สุด เราจึงยัด Any ใส่ทุกๆที่ของการประกาศตัวแปรซะเลย
  • เราสร้างอาร์เรย์ที่อีลีเมนต์ของมันเป็นข้อมูลชนิดอะไรก็ได้ เราจึงใช้ Any

มาดูตัวอย่างกันดีกว่าครับ...

TypeScript
1let list: any[] = [99, 'สล๊อต', true]

แล้วถ้าเราต้องการทำสิ่งตรงกันข้ามกับ Any คือการแทนที่ความไม่มีค่า เช่น null และ undefined หละ? ใน TypeScript เราสามารถใช้ Void เพื่อแทนชนิดข้อมูลนี้ได้ครับ

TypeScript
1let unusable: void = undefined

จะเห็นได้ชัดว่าในการประกาศตัวแปรประเภท void นั้นแทบไม่มีประโยชน์เลย ใครจะทะลึ่งไปประกาศตัวแปรมาเก็บค่า undefined หรือ null หละจริงไหมครับ? ฉะนั้นแล้วประโยชน์ของ void จึงเป็นการใช้ควบคู่ในการบอกว่าไม่มีสิ่งใด return ออกจากฟังก์ชันมากกว่า

TypeScript
1function setName(name: string): void {
2 this.name = name
3}

Type Assertions

เมื่อเรามีตัวแปรประเภท Any แต่ต้องการบอก compiler ของ TypeScript ว่า เห้ยๆ เชื่อฉันนะ ไอ้เนี่ยมันเป็นข้อมูลชนิด xXx หละ นี่หละครับที่เรียกว่า type assertion

TypeScript
1let iAmString: any = 'Hello ชาวโลก'
2// เพื่อให้สามารถเรียก length ของ string ได้
3// จึงต้องบอก TypeScript ว่าตัวแปรของเราเป็น string นะก่อน
4let strLen: number = (<string>iAmString).length
5// หรือ
6let strLen: number = (iAmString as string).length

จบไปแล้วครับกับเรื่องของชนิดข้อมูลพื้นฐานใน TypeScript ตอนหน้าเราจะมาเรียนรู้ถึงเรื่องของคลาสใน TypeScript กันบ้างว่ามีสิ่งใดเพิ่มเติมจาก ES2015 และช่วยให้เราเขียนโค๊ดได้ง่ายขึ้นอย่างไร

สารบัญ

สารบัญ

  • TypeScript คืออะไร
  • ข้อดีของการใช้ TypeScript
  • ข้อควรรู้ทั่วไปเกี่ยวกับ TypeScript
  • ชนิดข้อมูลพื้นฐานใน TypeScript
  • ชนิดข้อมูลประเภท Array, Tuple และ Enum
  • ชนิดข้อมูลประเภท Any และ Void
  • Type Assertions