- เป็นทั้ง รีลีสสุดท้าย ของโค้ดเบสปัจจุบันที่พัฒนาบน JavaScript และเป็น รีลีสสะพานเชื่อม เพื่อเตรียมเปลี่ยนผ่านไปสู่ TypeScript 7.0 ซึ่งเป็นเนทีฟพอร์ตที่เขียนด้วย Go
- รวมการปรับปรุงด้านการอนุมานชนิดและการตีความโมดูล เช่น ผ่อนปรนความไวต่อบริบท ของฟังก์ชันที่ไม่ได้ใช้
this และรองรับ subpath imports ที่ขึ้นต้นด้วย #/
- ปรับค่าเริ่มต้นของตัวเลือกคอมไพเลอร์ให้ทันสมัยครั้งใหญ่ เช่น เปลี่ยนค่าเริ่มต้น
strict เป็น true, ค่าเริ่มต้น target เป็น es2025, และค่าเริ่มต้น types เป็น []
- เลิกใช้ตัวเลือกแบบ legacy จำนวนมาก เช่นเป้าหมาย ES5, โมดูล AMD/UMD/SystemJS,
--baseUrl, --moduleResolution node10 เป็นต้น
- เพิ่ม การรองรับชนิดสำหรับข้อเสนอ ECMAScript Stage 4 ล่าสุด เช่น Temporal API,
getOrInsert/getOrInsertComputed ของ Map และ RegExp.escape
ตำแหน่งของ TypeScript 6.0
- เป็น รีลีสสุดท้าย บนโค้ดเบส JavaScript ปัจจุบัน และทำหน้าที่เป็นสะพานสำหรับการเปลี่ยนผ่านไปยัง TypeScript 7.0 (เนทีฟพอร์ตด้วย Go)
- TypeScript 7.0 ใช้ประโยชน์จาก เนทีฟโค้ดและมัลติเธรดแบบ shared memory และตอนนี้ใกล้เสร็จสมบูรณ์มากแล้ว
- การเปลี่ยนแปลงส่วนใหญ่ใน 6.0 มีไว้เพื่อ ปรับแนวทางและเตรียมพร้อม สำหรับการนำ 7.0 มาใช้
- สามารถทดลอง TypeScript 7.0 ล่วงหน้าได้ผ่าน ส่วนขยาย VS Code หรือ แพ็กเกจ npm
การเปลี่ยนแปลงหลัง Beta และ RC
- ปรับการตรวจสอบชนิดของ function expression ในการเรียกแบบ generic (โดยเฉพาะ generic JSX expression) — ช่วยจับบั๊กในโค้ดเดิมได้มากขึ้น แต่อาจทำให้บาง generic call ต้องระบุ type argument อย่างชัดเจน
- ขยายการเลิกใช้ ไวยากรณ์ import assertion (
assert) ให้ครอบคลุมถึงการเรียก import() ด้วย
- อัปเดต DOM types — สะท้อนมาตรฐานเว็บล่าสุด รวมถึงการปรับที่เกี่ยวข้องกับ Temporal API
ผ่อนปรนความไวต่อบริบทของฟังก์ชันที่ไม่ได้ใช้ this
- ระหว่างการอนุมานชนิด TypeScript จะจัดฟังก์ชันที่มีพารามิเตอร์ไม่มีชนิดระบุชัดเจนให้เป็น ฟังก์ชันไวต่อบริบท (contextually sensitive function) และประมวลผลลำดับหลัง
- ฟังก์ชันที่เขียนด้วย method syntax จะมีพารามิเตอร์
this โดยนัย ทำให้ ต่างจาก arrow function ตรงที่ถูกถือว่าไวต่อบริบทเสมอ
- ส่งผลให้บางครั้งการอนุมานชนิดล้มเหลวตามลำดับของเมธอดภายใน object literal
- ใน TypeScript 6.0 ฟังก์ชันที่ไม่ได้ใช้
this จริง ๆ จะไม่ถูกมองว่าไวต่อบริบทอีกต่อไป
- ฟังก์ชันเหล่านี้จึงได้ ลำดับความสำคัญสูงขึ้นในการอนุมานชนิด และอนุมานได้ถูกต้องโดยไม่ขึ้นกับลำดับของเมธอด
- พัฒนาจาก ผลงาน ของ Mateusz Burzyński
รองรับ Subpath Imports ที่ขึ้นต้นด้วย #/
- ฟีเจอร์ subpath imports ของ Node.js คือการกำหนด alias ให้โมดูลภายในแพ็กเกจผ่านฟิลด์
imports ใน package.json
- ก่อนหน้านี้จำเป็นต้องมีอักขระหลัง
# เสมอ จึงไม่สามารถใช้พาธที่ขึ้นต้นด้วย #/ ได้
- ทำให้นักพัฒนาที่คุ้นกับคอนเวนชันคำนำหน้า
@/ ของ bundler สับสน
- ล่าสุด Node.js เริ่มรองรับ subpath imports ที่ขึ้นต้นด้วย
#/
- ทำให้แมปแบบกระชับในรูป
"#/*": "./dist/*" ได้
- TypeScript 6.0 รองรับสิ่งนี้ในตัวเลือก
--moduleResolution nodenext และ bundler
- พัฒนาจาก ผลงาน ของ magic-akari
อนุญาตให้ใช้ --moduleResolution bundler ร่วมกับ --module commonjs
- เดิมที
--moduleResolution bundler ใช้ได้เฉพาะกับ --module esnext หรือ --module preserve
- จากการเลิกใช้
--moduleResolution node (node10) ทำให้ ชุดค่าผสมใหม่นี้เป็นเส้นทางอัปเกรดที่เหมาะสมที่สุดสำหรับหลายโปรเจกต์
- ในระยะยาวแนะนำให้ย้ายไปใช้
--module preserve + --moduleResolution bundler หรือ --module nodenext
แฟล็ก --stableTypeOrdering
- type ID ที่ TypeScript กำหนดให้ชนิดภายในจะขึ้นกับลำดับการประมวลผล และใช้สิ่งนี้ในการจัดเรียง union type
- จึงอาจเกิดพฤติกรรมคาดเดายากที่ ผลลัพธ์ declaration emit เปลี่ยนไปตามลำดับการประกาศ
- TypeScript 7.0 จะเพิ่ม การตรวจสอบชนิดแบบขนาน จึงใช้ อัลกอริทึมจัดเรียงแบบกำหนดแน่นอนตามเนื้อหา เพื่อแก้ปัญหา ID ที่ไม่แน่นอน
- เช่น
100 | 500 จะถูกพิมพ์ออกมาในลำดับเดิมเสมอ
- หากเปิดแฟล็ก
--stableTypeOrdering ใน 6.0 จะทำให้ พฤติกรรมการจัดเรียงชนิดตรงกับ 7.0 และลดความต่างระหว่างสองโค้ดเบส
- อาจทำให้ ประสิทธิภาพลดลงได้สูงสุด 25% ในการตรวจสอบชนิด
- หากเกิด type error จากความต่างในการอนุมาน สามารถแก้ได้ด้วยการเพิ่ม type argument หรือ variable annotation แบบชัดเจน
- แฟล็กนี้มีไว้ เพื่อวินิจฉัยการย้ายจาก 6.0 ไป 7.0 เท่านั้น ไม่แนะนำให้ใช้ระยะยาว
ตัวเลือก es2025 (target และ lib)
- ES2025 ไม่มีฟีเจอร์ภาษา JavaScript ใหม่ แต่เพิ่ม ชนิดของ built-in API (เช่น
RegExp.escape)
Promise.try, เมธอดของ Iterator, และเมธอดของ Set ที่เดิมอยู่ใน esnext ถูก ย้ายไปยัง es2025
- พัฒนาจาก ผลงาน ของ Kenta Moriuchi
รองรับชนิดของ Temporal API
- รวม built-in type ของ ข้อเสนอ Temporal ที่ไปถึง Stage 4 แล้วไว้ใน TypeScript 6.0
- ใช้งานได้ด้วย
--target esnext หรือ "lib": ["esnext"] (หรือแบบแยกละเอียด esnext.temporal)
- ใช้ API อย่าง
Temporal.Now.instant().subtract() และ .add() ได้อย่างปลอดภัยด้านชนิด
- ตอนนี้ใช้งานได้แล้วในหลาย runtime และด้วยการไปถึง Stage 4 จึงเป็น ส่วนหนึ่งของภาษา JavaScript อย่างเป็นทางการ
- พัฒนาจาก ผลงาน ของ Renegade334
รองรับชนิดของเมธอด "upsert" ใน Map (getOrInsert / getOrInsertComputed)
- ทำให้แพตเทิร์นซ้ำ ๆ ในการตรวจสอบว่าคีย์มีอยู่ใน Map หรือไม่ และกำหนดค่าเริ่มต้นเมื่อไม่มี สั้นลง
- ข้อเสนอ "upsert" ของ ECMAScript ไปถึง Stage 4 แล้ว จึงเพิ่มเมธอดใหม่ 2 ตัวใน
Map และ WeakMap
getOrInsert: ถ้าไม่มีคีย์ จะใส่ค่าเริ่มต้นที่กำหนดแล้วคืนค่านั้น
getOrInsertComputed: หากการสร้างค่าเริ่มต้นมีต้นทุนสูง สามารถคำนวณแบบ lazy ผ่าน callback ได้
- callback รับคีย์เป็นอาร์กิวเมนต์ จึงใช้สร้างค่าเริ่มต้นตามคีย์ได้ด้วย
- ถูกเพิ่มใน lib
esnext และใช้งานได้ทันทีใน TypeScript 6.0
- พัฒนาจาก ผลงาน ของ Renegade334
RegExp.escape
- ฟังก์ชัน
RegExp.escape สำหรับ escape อักขระพิเศษใน regular expression ไปถึง Stage 4 แล้ว
- รวมอยู่ใน lib
es2025 และใช้งานได้ใน TypeScript 6.0
- พัฒนาจาก ผลงาน ของ Kenta Moriuchi
รวม dom.iterable และ dom.asynciterable เข้ากับ lib dom
- เดิมหากต้องการใช้ iteration กับ
NodeList, HTMLCollection เป็นต้น จำเป็นต้องระบุ "lib": ["dom", "dom.iterable"]
- ใน TypeScript 6.0 เนื้อหาของ
lib.dom.iterable.d.ts และ lib.dom.asynciterable.d.ts ถูก รวมเข้ากับ lib.dom.d.ts อย่างสมบูรณ์
dom.iterable และ dom.asynciterable ยังอ้างอิงได้ แต่เป็น ไฟล์ว่าง
- เบราว์เซอร์สมัยใหม่หลักทั้งหมดรองรับฟีเจอร์นี้อยู่แล้ว จึงเป็น การปรับปรุงด้านความสะดวก เพื่อลดจุดที่ทำให้สับสนบ่อย
การเปลี่ยนค่าเริ่มต้นสำคัญ
- ค่าเริ่มต้น
strict เป็น true: โปรเจกต์ใหม่ส่วนใหญ่มักต้องการ strict mode ดังนั้นโปรเจกต์ที่เคยพึ่งพา false ต้องตั้ง "strict": false เองอย่างชัดเจน
- ค่าเริ่มต้น
module เป็น esnext: สะท้อนความจริงที่ว่า ESM กลายเป็นรูปแบบโมดูลหลักแล้ว
- ค่าเริ่มต้น
target เป็นเวอร์ชัน ES ล่าสุด (ปัจจุบันคือ es2025): runtime แบบ evergreen แพร่หลายจนไม่จำเป็นต้อง transpile ไปเวอร์ชันเก่า
- ค่าเริ่มต้น
noUncheckedSideEffectImports เป็น true: ช่วยตรวจจับการพิมพ์ผิดใน import ที่มีไว้เพื่อ side effect เท่านั้น
- ค่าเริ่มต้น
libReplacement เป็น false: ป้องกันความล้มเหลวในการ resolve โมดูลโดยไม่จำเป็นและลดจำนวนไฟล์ที่ต้องเฝ้าดู จึงช่วยเพิ่มประสิทธิภาพพื้นฐาน
เปลี่ยนค่าเริ่มต้น rootDir เป็น .
- เดิมหากไม่ระบุ ระบบจะอนุมานจาก ไดเรกทอรีร่วม ของไฟล์ input ที่ไม่ใช่ declaration ทั้งหมด
- ทำให้การตัดสินว่าไฟล์ใดอยู่ในโปรเจกต์ต้องโหลดและ parse โปรเจกต์นั้นก่อน
- ใน TypeScript 6.0 ค่าเริ่มต้นถูกกำหนดตายตัวเป็น ไดเรกทอรีที่มี
tsconfig.json อยู่
- หากไฟล์ซอร์สอยู่ลึกกว่า
tsconfig.json จำเป็นต้องตั้งค่า "rootDir": "./src" เป็นต้นอย่างชัดเจน
- ถ้าไม่ตั้ง อาจได้โครงสร้างผลลัพธ์ที่ไม่ตั้งใจ เช่น
./dist/src/index.js
เปลี่ยนค่าเริ่มต้น types เป็น []
- เดิมจะรวม ทุกแพ็กเกจ ใน
node_modules/@types โดยอัตโนมัติ ทำให้เกิด overhead สูงมากในเวลา build
- ในรีโพซิทอรีทั่วไป มักมีแพ็กเกจ
@types หลายร้อยตัวถูกดึงเข้ามาแบบ transitive
- TypeScript 6.0 จึงเปลี่ยนค่าเริ่มต้นเป็น
[] (อาร์เรย์ว่าง) เพื่อป้องกันการโหลด declaration file ที่ไม่จำเป็น
- พบกรณีจริงที่ เวลา build ดีขึ้น 20–50%
- โปรเจกต์ส่วนใหญ่จะต้องตั้งค่าอย่างชัดเจน เช่น
"types": ["node"] หรือ "types": ["node", "jest"]
- สามารถคืนพฤติกรรมเดิมได้ด้วย
"types": ["*"]
รายการที่เลิกใช้ (Deprecation)
เลิกใช้ target: es5
- เป้าหมาย ES5 แทบไม่มีกรณีใช้งานแล้ว จากการปลดระวาง IE และการแพร่หลายของเบราว์เซอร์แบบ evergreen
- เป้าหมายขั้นต่ำเปลี่ยนเป็น ES2015 และหากยังต้องการผลลัพธ์แบบ ES5 แนะนำให้ใช้คอมไพเลอร์ภายนอก
เลิกใช้ --downlevelIteration
- มีผลเฉพาะกับการ emit แบบ ES5 เท่านั้น ดังนั้นเมื่อเลิกใช้เป้าหมาย ES5 ก็หมดเหตุผลในการมีอยู่
เลิกใช้ --moduleResolution node (node10)
- สะท้อนอัลกอริทึมการ resolve โมดูลของ Node.js 10 ซึ่งไม่ตรงกับพฤติกรรมของ Node.js รุ่นใหม่
- แนะนำให้ย้ายไปใช้
nodenext (เจาะจง Node.js โดยตรง) หรือ bundler (ใช้ bundler/Bun)
เลิกใช้ค่าโมดูล AMD, UMD, SystemJS
--module amd, --module umd, --module systemjs, --module none ไม่ได้รับการรองรับอีกต่อไป
- เมื่อ ESM รองรับอย่างแพร่หลายในเบราว์เซอร์และ Node.js แล้ว จึงควรเปลี่ยนไปใช้ bundler หรือกำหนดเป้าหมาย ESM
เลิกใช้ --baseUrl
- เดิมมักใช้เป็นคำนำหน้าของ
paths แต่ก็ยังทำหน้าที่เป็น lookup root ของการ resolve โมดูลด้วย จึงก่อปัญหาการ resolve path ที่ไม่ตั้งใจ
- แนวทางย้ายคือเอา
baseUrl ออก แล้วเพิ่มคำนำหน้าโดยตรงในรายการ paths
- ตัวอย่าง:
"@app/*": ["app/*"] → "@app/*": ["./src/app/*"]
เลิกใช้ --moduleResolution classic
- เป็นอัลกอริทึมการ resolve โมดูลดั้งเดิมของ TypeScript ซึ่งตอนนี้ทุกกรณีใช้งานที่มีความเป็นจริงสามารถแทนที่ด้วย
nodenext หรือ bundler ได้
เลิกใช้ esModuleInterop false และ allowSyntheticDefaultImports false
- ไม่สามารถตั้งสองตัวเลือกนี้เป็น
false ได้อีก ทำให้ พฤติกรรม interop ที่ปลอดภัยเปิดใช้งานเสมอ
- อาจต้องปรับจาก
import * as express from "express" เป็น import express from "express"
เลิกใช้ --alwaysStrict false
- โค้ดทั้งหมดจะถูกมองว่าอยู่ใน JavaScript strict mode ดังนั้นโค้ดที่ใช้
await, static, private เป็นต้นเป็น identifier ทั่วไป จะต้องเปลี่ยนชื่อ
เลิกใช้ outFile
- เดิมเป็นฟีเจอร์รวมหลายไฟล์ input ให้เป็นไฟล์เดียว แต่ปัจจุบันมี bundler ภายนอก อย่าง Webpack, Rollup, esbuild, Vite มาทดแทนแล้ว
- เป็นการตัดสินใจเพื่อให้ TypeScript โฟกัสกับหน้าที่หลักคือ type checking และ declaration emit
เลิกใช้ไวยากรณ์ module แบบเก่า (การประกาศ namespace)
- ไวยากรณ์
module Foo { ... } ถูก เลิกใช้แบบเด็ดขาด และต้องใช้ namespace Foo { ... } แทน
- การประกาศ ambient module ในรูป
declare module "some-module" { ... } ยังรองรับเช่นเดิม
- มีจุดประสงค์เพื่อหลีกเลี่ยงการชนกับข้อเสนอ
module block ของ ECMAScript
เลิกใช้คีย์เวิร์ด Import asserts
- ต้องเปลี่ยนจาก
import ... asserts { type: "json" } เป็น import ... with { type: "json" }
- เป็นผลจากการที่ข้อเสนอ import assertions เปลี่ยนเป็นข้อเสนอ import attributes (
with)
เลิกใช้ directive no-default-lib
/// <reference no-default-lib="true"/> ไม่รองรับอีกต่อไป และแนะนำให้ใช้ --noLib หรือ --libReplacement
ระบุไฟล์ผ่าน command line เมื่อมี tsconfig.json แล้วจะเกิดข้อผิดพลาด
- หากรัน
tsc foo.ts แล้วมี tsconfig.json อยู่ในไดเรกทอรีเดียวกัน จะ เกิดข้อผิดพลาด
- สามารถละเว้นอย่างชัดเจนได้ด้วยแฟล็ก
--ignoreConfig
การเตรียมพร้อมสำหรับ TypeScript 7.0
- ตัวเลือกที่ถูกเลิกใช้ใน 6.0 ยังใช้งานต่อได้โดยไม่เกิดข้อผิดพลาดผ่านการตั้งค่า
"ignoreDeprecations": "6.0" แต่ จะถูกลบออกทั้งหมดใน 7.0
- สามารถใช้ เครื่องมือ ts5to6 เพื่อปรับค่าอย่าง
baseUrl, rootDir แบบอัตโนมัติได้
- TypeScript 7.0 มีกำหนดออกภายในไม่กี่เดือน และกำลังถูกนำไปใช้แล้วอย่างกว้างขวางในโค้ดเบสขนาดใหญ่ทั้งภายในและภายนอก Microsoft
- แนะนำให้ส่ง feedback ผ่าน native preview nightly build และ ส่วนขยาย VS Code
3 ความคิดเห็น
ตั้งตารอช่วงเวลาที่จะเปลี่ยนผ่านไปสู่คอมไพเลอร์ที่พัฒนาด้วย Go อย่างสมบูรณ์!
หืม? ต่อไป TypeScript จะเปลี่ยนเป็นเนทีฟที่พัฒนาด้วย Go เหรอ?
เฉพาะคอมไพเลอร์เท่านั้น