8 คะแนน โดย GN⁺ 2026-03-25 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • เป็นทั้ง รีลีสสุดท้าย ของโค้ดเบสปัจจุบันที่พัฒนาบน 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 ความคิดเห็น

 
tsboard 2026-03-26

ตั้งตารอช่วงเวลาที่จะเปลี่ยนผ่านไปสู่คอมไพเลอร์ที่พัฒนาด้วย Go อย่างสมบูรณ์!

 
princox 2026-03-25

หืม? ต่อไป TypeScript จะเปลี่ยนเป็นเนทีฟที่พัฒนาด้วย Go เหรอ?

 
helio 2026-03-25

เฉพาะคอมไพเลอร์เท่านั้น