- TypeScript 6.0 RC là bản phát hành trình biên dịch dựa trên JS cuối cùng và đồng bộ hóa hành vi, các giá trị mặc định và thứ tự với TypeScript 7.0 dựa trên Go sắp ra mắt.
- Bản phát hành này thắt chặt các thiết lập mặc định hiện đại (nghiêm ngặt, mô-đun ESNext, ES2025), giới thiệu Temporal, API ES2025 và các kiểu dữ liệu mới như Map upsert và RegExp.escape.
- Các thay đổi cấu hình chính bao gồm mảng kiểu mặc định trống, rootDir mặc định là thư mục cấu hình, và việc loại bỏ ES5, các hệ thống mô-đun cũ, baseUrl và các chế độ phân giải cũ.
- Các nhóm được khuyến khích nâng cấp lên phiên bản 6.0, sửa các lỗi không còn được hỗ trợ và tùy chọn sử dụng tham số --stableTypeOrdering để đảm bảo quá trình chuyển đổi sang TypeScript 7.0 diễn ra suôn sẻ hơn.
TypeScript 6.0 đã chính thức đạt mốc Release Candidate (RC).Và đây không chỉ là một bản cập nhật nhỏ thông thường. Đây là phiên bản chính cuối cùng chạy trên nền tảng JavaScript đã được sử dụng lâu năm của trình biên dịch và dịch vụ ngôn ngữ, ngay trước khi dự án chuyển sang một công cụ hoàn toàn mới, dựa trên Go trong TypeScript 7.0. Chỉ riêng điều đó thôi đã khiến phiên bản 6.0 trở thành một bản phát hành then chốt: đó là cây cầu bạn cần vượt qua trước khi mọi thứ bên trong thay đổi.
Bạn có thể bắt đầu dùng thử phiên bản RC ngay hôm nay bằng cách cài đặt nó từ npm. với:
npm install -D typescript@rc
Ý tưởng cốt lõi đằng sau TypeScript 6.0 là sự chuẩn bị và sự đồng bộ.Phiên bản này giúp quá trình chuyển đổi từ 5.9 sang 7.0 diễn ra suôn sẻ hơn, thắt chặt các thiết lập mặc định, loại bỏ những tính năng lỗi thời và bổ sung một vài tính năng cụ thể nhằm phản ánh hành vi trong tương lai hoặc hé lộ các khả năng sắp ra mắt của JavaScript như Temporal, API ES2025 và các phương thức “upsert” của Map. Cùng với đó, có một số tinh chỉnh nhỏ về hệ thống kiểu dữ liệu, các cờ biên dịch mới và các thiết lập mặc định cấu hình chắc chắn sẽ ảnh hưởng đến các dự án thực tế—đặc biệt là xung quanh... types, rootDirvà sự nghiêm khắc.
TypeScript 6.0 đóng vai trò là cầu nối đến TypeScript 7.0 dựa trên Go.
TypeScript 6.0 được thiết kế rõ ràng như là phiên bản phát hành chính cuối cùng cho nền tảng mã nguồn JavaScript hiện có.Nhóm TypeScript đã và đang viết lại trình biên dịch và dịch vụ ngôn ngữ thành một hệ thống hoàn chỉnh hơn. motor nativo en Go, tận dụng hiệu năng gốc và khả năng song song hóa bộ nhớ dùng chung. Công cụ mới này sẽ ra mắt với TypeScript 7.0 trở lên, và 6.0 nằm ngay trước đó như một giai đoạn chuyển tiếp.
Hầu hết các thay đổi và tính năng bị loại bỏ trong phiên bản 6.0 đều nhằm mục đích giúp bạn dễ dàng nâng cấp lên phiên bản 7.0 trong tương lai.Các tùy chọn không thể được hỗ trợ hiệu quả trong kiến trúc gốc, hệ thống mô-đun cũ và các đặc điểm kỳ lạ lâu năm sẽ bị loại bỏ hoặc được đánh dấu rõ ràng là lỗi thời với một lối thoát: bạn có thể thiết lập "ignoreDeprecations": "6.0" trong tsconfig.json Để tắt chẩn đoán lỗi thời trong phiên bản 6.0. Nhưng cờ đó sẽ không giúp ích gì cho bạn trong phiên bản 7.0 — các tùy chọn đó dự kiến sẽ bị loại bỏ hoàn toàn.
Nếu bạn có ý định "chờ đến phiên bản 7.0" trước khi dọn dẹp cấu hình, đó là một cái bẫy.Phiên bản 6.0 RC là phiên bản mà bạn cần phải sửa lỗi. tsconfigChuẩn hóa kiểu dữ liệu và xử lý các cờ lỗi thời. Việc thực hiện hai bước nhảy vọt lớn (5.x → 7.0) sẽ luôn gây ra nhiều thiệt hại hơn so với việc thực hiện 5.x → 6.0 → 7.0 với những thay đổi nhỏ hơn và được kiểm soát tốt hơn.
Những thay đổi so với phiên bản beta 6.0 là gì?
Giữa giai đoạn beta và RC, nhóm phát triển TypeScript chủ yếu tập trung vào việc điều chỉnh hành vi sao cho phù hợp với engine 7.0 trong tương lai.cộng thêm một vài tinh chỉnh nhỏ về kiểm tra kiểu dữ liệu và định nghĩa kiểu DOM.
Một thay đổi quan trọng ảnh hưởng đến việc kiểm tra kiểu dữ liệu của các biểu thức hàm được truyền cho các lệnh gọi chung.Đặc biệt là trong ngữ cảnh JSX. Khi các hàm chung được gọi với các hàm gọi lại (ví dụ: trong React hoặc các thành phần JSX khác), RC sẽ thắt chặt quá trình suy luận để phản ánh chính xác hơn những gì phiên bản 7.0 sẽ thực hiện. Trên thực tế, bạn có thể nhận thấy rằng một số lệnh gọi dựa vào suy luận ngầm giờ đây yêu cầu một đối số kiểu rõ ràng để đảm bảo kiểm tra kiểu hoạt động bình thường, nhưng bạn cũng sẽ phát hiện ra nhiều lỗi thực sự hơn trong mã hiện có.
Việc loại bỏ cú pháp khẳng định nhập khẩu cũng đã được mở rộng.TypeScript đã đưa ra cảnh báo về phiên bản cũ. import ... assert {...} cú pháp trong các import tĩnh do đề xuất ECMAScript chuyển sang sử dụng thuộc tính import với withHiện tại, việc loại bỏ tính năng này cũng áp dụng cho việc nhập khẩu động bằng cách sử dụng... import() với các đối tượng khẳng định như import(..., { assert: {...}})Hướng đi đã rõ ràng: chuyển sang nhập thuộc tính ở mọi nơi.
Các kiểu thư viện DOM đã được cập nhật để phù hợp với các tiêu chuẩn nền tảng web hiện hành.Bao gồm cả các bản cập nhật cho các API liên quan đến Thời gian trong ngữ cảnh web. Nếu bạn đang xây dựng ứng dụng trình duyệt, bạn sẽ được hưởng lợi từ các kiểu dữ liệu chính xác hơn và các công cụ chỉnh sửa tốt hơn xung quanh các API mới này.
Ít nhạy cảm với ngữ cảnh hơn đối với các hàm không bao giờ được sử dụng. this
TypeScript 6.0 giới thiệu một thay đổi tinh tế nhưng rất thiết thực trong cách xử lý các hàm mà không cần khai báo rõ ràng. this sử dụng trong quá trình suy luận kiểuTrong lịch sử, các hàm có tham số thiếu kiểu dữ liệu rõ ràng có thể được coi là "nhạy cảm theo ngữ cảnh", nghĩa là tham số và kiểu dữ liệu của chúng... this Các kiểu dữ liệu phụ thuộc vào nơi chúng được sử dụng. Điều đó ảnh hưởng đến suy luận kiểu chung và có thể dẫn đến hành vi bất thường tùy thuộc vào cú pháp hàm.
Hãy xem xét một hàm hỗ trợ chung sử dụng một cặp nhà sản xuất và người tiêu dùng.:
declare function callIt<T>(obj: {
produce: (x: number) => T,
consume: (y: T) => void,
}): void;
// Arrow functions: everything infers fine
callIt({
produce: (x: number) => x * 2,
consume: y => y.toFixed(),
});
// Flipped property order still fine with arrows
callIt({
consume: y => y.toFixed(),
produce: (x: number) => x * 2,
});
Nhưng với cú pháp phương thức, hành vi trước đó có thể gây bất ngờ.Cùng một logic đó, được viết dưới dạng phương thức, có thể bị lỗi khi các thuộc tính được sắp xếp lại, bởi vì TypeScript đã bỏ qua các hàm "nhạy cảm theo ngữ cảnh" khi suy luận các đối số chung. Các phương thức ngầm định có một this tham số, điều này đã đẩy họ vào danh mục nhạy cảm ngay cả khi this Thực tế là nó chưa từng được nhắc đến.
Trong phiên bản 6.0, các hàm không bao giờ đọc this hiện được coi là ít nhạy cảm với ngữ cảnh hơn.Nói cách khác, nếu trình biên dịch thấy rằng this Nếu nó không được sử dụng bên trong một hàm, nó sẽ không gây bất lợi cho hàm đó trong quá trình suy luận. Điều đó có nghĩa là cú pháp phương thức và cú pháp mũi tên giờ đây nhất quán hơn nhiều trong các kịch bản suy luận tổng quát, và hành vi kỳ lạ "hoạt động theo một thứ tự thuộc tính, nhưng lại thất bại theo thứ tự khác" sẽ biến mất trong những trường hợp này.
Thay đổi này giúp cải thiện việc ưu tiên các ứng viên cho quá trình suy luận kiểu.: hoạt động mà không cần sử dụng this trở thành nguồn thông tin ưu tiên cao hơn khi suy luận các đối số kiểu như THiệu ứng này ít bí ẩn hơn. unknown các kiểu dữ liệu và khả năng suy luận ổn định hơn trong quá trình tái cấu trúc. Công việc này do Mateusz Burzyński đóng góp.
Hỗ trợ cho Node.js #/ nhập khẩu đường dẫn con
Tính năng "nhập khẩu đường dẫn con" của Node cho phép các gói định nghĩa các bí danh nhập khẩu nội bộ thông qua imports lĩnh vực trong package.jsonCác bí danh này đơn giản hóa việc nhập khẩu bằng cách tránh các đường dẫn tương đối sâu. Trước đây, mỗi khóa đường dẫn con phải có ít nhất một phân đoạn sau phần đầu tiên. #, đó là một hạn chế nhỏ nhưng gây khó chịu đối với những người đã quen với các quy ước của trình đóng gói như @/....
TypeScript 6.0 hiện hỗ trợ nhập khẩu đường dẫn con bắt đầu bằng #/Điều này phù hợp với hành vi mới hơn của Node 20. Có nghĩa là bạn có thể sử dụng cấu hình như sau:
{
"name": "my-package",
"type": "module",
"imports": {
"#": "./dist/index.js",
"#/*": "./dist/*"
}
}
Với thiết lập này, các mô-đun bên trong gói—và thậm chí cả người dùng—có thể nhập dữ liệu thông qua một giao thức ngắn gọn. #/... tiếp đầu ngữ thay vì các đường đi tương đối dài như ../../utils.jsTypeScript hiểu mẫu này khi --moduleResolution được thiết lập để node20, nodenext, hoặc là bundlerPhản ánh ngữ nghĩa của Node hiện đại. Cải tiến này được thực hiện bởi người đóng góp magic-akari.
Sử dụng --moduleResolution bundler với --module commonjs
Trước đây, --moduleResolution bundler chỉ có thể được sử dụng với --module esnext or preserveDo sự lỗi thời của các phiên bản cũ hơn. node/node10 Chế độ phân giải mô-đun, nhiều dự án cần một lộ trình chuyển đổi phù hợp với đầu ra CommonJS hiện tại của họ.
TypeScript 6.0 hiện cho phép kết hợp --moduleResolution bundler với --module commonjsSự kết hợp này thường là một bước đệm thiết thực cho các codebase vẫn đang phát ra CommonJS nhưng đang chuyển sang quy trình làm việc tập trung vào bundler hoặc logic phân giải mới hơn. Từ đó, các dự án có thể lên kế hoạch chuyển đổi dài hạn sang một trong hai:
module: "preserve"vớimoduleResolution: "bundler"dành cho các ứng dụng web được đóng gói và các thiết lập tương tự, hoặcmodule: "nodenext"Dành cho các môi trường nhắm trực tiếp đến Node.js hiện đại.
Sự thay đổi này đặc biệt quan trọng đối với các đội rời đi. moduleResolution: node sau Nhưng chưa sẵn sàng hoàn toàn đón nhận kết quả đầu ra của ESM. Nó cung cấp cho bạn một lộ trình theo từng giai đoạn thay vì một lộ trình đột ngột.
--stableTypeOrdering cờ để mô phỏng thứ tự 7.0
Một trong những nâng cấp kiến trúc quan trọng trong TypeScript 7.0 là kiểm tra kiểu song song.Việc chạy nhiều trình kiểm tra song song có nghĩa là các phần khác nhau của chương trình có thể được truy cập theo các thứ tự khác nhau. Nếu ID kiểu và thứ tự ký hiệu phụ thuộc vào thứ tự truy cập, bạn có thể gặp phải tình trạng thứ tự hợp nhất không xác định, thứ tự thuộc tính không xác định, và thậm chí là những khác biệt hiếm gặp trong chẩn đoán.
Các phiên bản TypeScript cũ hơn gán ID kiểu nội bộ dựa trên thứ tự gặp gỡ.Những ID đó sau đó được sử dụng để sắp xếp các thứ như loại liên hợp và thuộc tính. Đó là lý do tại sao những chỉnh sửa tưởng chừng như vô hại—như việc thêm một cái mới—lại gây ra lỗi. const trước một hàm hiện có—có thể đảo ngược thứ tự của các liên kết chữ trong được phát ra .d.ts các tệp, hoặc thay đổi cách in một số loại tệp trong trình soạn thảo của bạn.
TypeScript 7.0 chuyển sang sử dụng thứ tự xác định, dựa trên nội dung cho các đối tượng nội bộ.Mỗi kiểu dữ liệu hoặc ký hiệu được sắp xếp theo cấu trúc của nó, chứ không phải theo thứ tự truy cập ngẫu nhiên, vì vậy cùng một chương trình sẽ luôn tạo ra cùng một thứ tự bất kể tính song song hay thứ tự biên dịch. Điều đó loại bỏ bí ẩn "tại sao phép hợp của tôi lại đột nhiên đảo ngược?".
Để giúp bạn so sánh hành vi giữa phiên bản 6.0 và 7.0, RC giới thiệu --stableTypeOrderingKhi cờ này được bật, TypeScript 6.0 sẽ áp dụng thuật toán sắp xếp kiểu xác định tương tự như TypeScript 7.0. Kết quả là số lượng khác biệt trong các tệp khai báo được tạo ra sẽ ít hơn đáng kể và việc so sánh giữa đầu ra của 6.x và 7.x sẽ dễ dự đoán hơn.
Tuy nhiên, thuyết định mệnh không phải là tự do.. Cho phép --stableTypeOrdering Việc này có thể làm chậm quá trình kiểm tra kiểu dữ liệu lên đến khoảng 25% tùy thuộc vào mã nguồn của bạn. Nó được dùng như một công cụ hỗ trợ chẩn đoán và chuyển đổi, chứ không phải là một thiết lập hiệu năng cố định mãi mãi.
Nếu bạn chỉ thấy lỗi kiểu dữ liệu khi --stableTypeOrdering Được bậtĐiều đó thường có nghĩa là đoạn mã trước đây của bạn dựa vào thứ tự sắp xếp kiểu dữ liệu cũ, gần như ngẫu nhiên, để quá trình suy luận "hoạt động trơn tru". Các biện pháp khắc phục thường bao gồm việc làm cho các kiểu dữ liệu trở nên rõ ràng hơn—thêm một đối số kiểu vào một lệnh gọi chung gây ra sự cố, hoặc chú thích một biến với một giao diện cụ thể thay vì hoàn toàn dựa vào suy luận cho một đối tượng phức tạp.
Mới es2025 tùy chọn mục tiêu và thư viện
TypeScript 6.0 bổ sung thêm một tính năng mới. es2025 tùy chọn cho cả hai target và libMặc dù ES2025 không giới thiệu cú pháp cốt lõi mới so với các năm trước, nhưng nó đã tích hợp một số API tiêu chuẩn hóa trước đây bị hạn chế truy cập. esnext.
Bằng cách nhắm mục tiêu hoặc bao gồm es2025Bạn sẽ nhận được thông tin cập nhật về kiểu dữ liệu cho các hàm tích hợp mới. Lượt thích RegExp.escapevà một số API được chuyển ra khỏi esnext trong es2025Điều đó bao gồm những thứ như... Promise.try, các trình trợ giúp lặp và các phần bổ sung Set Các phương pháp đã đạt đến độ hoàn thiện về mặt đặc tả kỹ thuật. Công trình này do Kenta Moriuchi đóng góp.
Câu chuyện tổng quát hơn là mặc định target Trong phiên bản 6.0, tính năng này hiện đang theo dõi năm ECMAScript hiện tại.Điều này hiện tại sẽ đưa bạn đến với ES2025 nếu bạn không chỉ định mục tiêu. Điều đó phù hợp hơn với thực tế của các runtime luôn được cập nhật và các công cụ hiện đại.
Các kiểu dữ liệu tích hợp sẵn cho API Thời gian
Đề xuất Temporal được chờ đợi từ lâu đã bước vào giai đoạn 3 và dự kiến sẽ thay thế đề xuất tai tiếng trước đó. Date API dành cho các công việc liên quan đến ngày/giờ nghiêm túcTypeScript 6.0 hiện đã tích hợp sẵn các kiểu dữ liệu hạng nhất cho Temporal, vì vậy bạn có thể bắt đầu viết mã dựa trên Temporal với đầy đủ tính an toàn kiểu dữ liệu và hỗ trợ trình soạn thảo.
Để kích hoạt các kiểu dữ liệu thời gian, bạn có thể sử dụng --target esnext hoặc cấu hình thư viện của bạn một cách rõ ràng thông qua một cái gì đó tương tự như:
{
"compilerOptions": {
"lib":
}
}
Hoặc bạn có thể chọn chỉ sử dụng tập hợp con theo thời gian với "esnext.temporal" Nếu bạn muốn cấu hình chi tiết hơn. Sau khi kích hoạt, bạn có thể viết mã theo kiểu như sau:
let yesterday = Temporal.Now.instant().subtract({
hours: 24,
});
let tomorrow = Temporal.Now.instant().add({
hours: 24,
});
console.log(`Yesterday: ${yesterday}`);
console.log(`Tomorrow: ${tomorrow}`);
Temporal đã được hỗ trợ trong một số runtime và có thể được bổ sung bằng polyfill trong các runtime khác.Vì vậy, các kiểu dữ liệu này thực sự có thể sử dụng được hiện nay. Tài liệu đang được hoàn thiện trên MDN (với một số thiếu sót vẫn đang được bổ sung). Các định nghĩa kiểu dữ liệu được đóng góp bởi người dùng GitHub Renegade334.
Hỗ trợ Upsert: Map.getOrInsert và getOrInsertComputed
Các nhà phát triển JavaScript đã tự tay viết các mẫu "kiểm tra rồi thiết lập rồi lấy" trên Map trong nhiều nămMột mẫu điển hình kiểm tra xem khóa có tồn tại hay không, đặt giá trị mặc định nếu không, và cuối cùng trả về một giá trị—một đoạn mã lặp đi lặp lại dễ gây lỗi hoặc lặp lại ở khắp mọi nơi.
Đề xuất “upsert” của ECMAScript (hiện đang ở giai đoạn 4) giới thiệu getOrInsert và getOrInsertComputed on Map và WeakMapTypeScript 6.0 bổ sung hỗ trợ kiểu dữ liệu cho các phương thức này trong... esnext lib, vì vậy bạn có thể bắt đầu viết các câu lệnh upsert mang tính khai báo hơn ngay lập tức.
Với getOrInsertmột kiểu mẫu dài dòng như thế này:
function processOptions(compilerOptions: Map<string, unknown>) {
let strictValue: unknown;
if (compilerOptions.has("strict")) {
strictValue = compilerOptions.get("strict");
} else {
strictValue = true;
compilerOptions.set("strict", strictValue);
}
// ...
}
Có thể thu gọn thành một dòng duy nhất:
function processOptions(compilerOptions: Map<string, unknown>) {
let strictValue = compilerOptions.getOrInsert("strict", true);
// ...
}
Bạn đồng hành getOrInsertComputed lý tưởng cho các khoản nợ quá hạn đắt đỏ.—Nó nhận một hàm callback chỉ được gọi khi khóa bị thiếu. Hàm callback đó thậm chí có thể nhận khóa làm tham số, cho phép bạn suy ra giá trị mặc định từ chính khóa đó. Các định nghĩa kiểu dữ liệu của TypeScript nắm bắt chính xác những hành vi này, một lần nữa nhờ vào sự đóng góp của Renegade334.
RegExp.escape và xây dựng biểu thức chính quy an toàn hơn
Nếu bạn đã từng ghép các chuỗi do người dùng cung cấp vào một biểu thức chính quy, bạn sẽ biết rằng bạn cần phải thoát các ký tự đặc biệt trước khi sử dụng.—nhưng hầu hết các codebase đều tự viết lại phần thoát ký tự trong một hàm hỗ trợ hoặc bỏ qua hoàn toàn. Đề xuất Thoát ký tự biểu thức chính quy (hiện đang ở giai đoạn 4) chuẩn hóa điều này với RegExp.escape.
TypeScript 6.0 cung cấp các kiểu dữ liệu cho RegExp.escape theo es2025 libĐiều đó có nghĩa là khi bạn nhắm mục tiêu hoặc bao gồm ES2025, bạn có thể an toàn viết các hàm hỗ trợ như sau:
function matchWholeWord(word: string, text: string) {
const escapedWord = RegExp.escape(word);
const regex = new RegExp(`\\b${escapedWord}\\b`, "g");
return text.match(regex);
}
Không cần đến chức năng thoát hiểm bằng tay nữa.và TypeScript sẽ hiểu đầy đủ và kiểm tra kiểu dữ liệu của API. Việc bổ sung này, giống như công việc liên quan đến mục tiêu ES2025, đến từ Kenta Moriuchi.
dom Thư viện hiện đã bao gồm các API lặp và lặp bất đồng bộ.
Trước đây, TypeScript chia việc hỗ trợ trình lặp DOM thành các phần riêng biệt. dom, dom.iterablevà dom.asynciterableNếu bạn muốn lặp lại NodeList or HTMLCollection với for...ofBạn phải nhớ thêm vào dom.iterable trong "lib" cấu hình cùng với domĐây là một nguồn gây nhầm lẫn phổ biến, đặc biệt là vì tất cả các trình duyệt hiện đại đều hỗ trợ các đối tượng có thể lặp lại và các đối tượng có thể lặp lại bất đồng bộ trên các tập hợp DOM.
Trong TypeScript 6.0, lib.dom.iterable.d.ts và lib.dom.asynciterable.d.ts được hợp nhất một cách hiệu quả vào lib.dom.d.ts. Điều đó có nghĩa là sử dụng "dom" Hiện tại, chức năng này cung cấp cho bạn hành vi lặp lại và lặp lại bất đồng bộ theo mặc định.
Bạn vẫn có thể đề cập đến dom.iterable và dom.asynciterable trong tsconfigNhưng những tập tin đó giờ chỉ còn là những khung rỗng. Nếu cấu hình trước đây của bạn trông như thế này:
{
"compilerOptions": {
"lib":
}
}
Bạn có thể đơn giản hóa một cách an toàn thành chỉ "dom"và lặp lại các tập hợp DOM như document.querySelectorAll("div") Vẫn sẽ kiểm tra lại kiểu chữ:
for (const element of document.querySelectorAll("div")) {
console.log(element.textContent);
}
Đây là một công việc dọn dẹp nhỏ nhưng đáng hoan nghênh. Điều này giúp đồng bộ hóa thư viện DOM mặc định với thực tế của các trình duyệt hiện tại và loại bỏ một vấn đề khó giải quyết khác trong quá trình thiết lập dự án.
Các giá trị mặc định, tính năng bị loại bỏ và những thay đổi gây lỗi trong TypeScript 6.0
Bên cạnh những API bóng bẩy, phiên bản 6.0 còn thực hiện một số thay đổi mang tính định hướng nhất đối với các thiết lập mặc định của TypeScript kể từ phiên bản 1.0.Những thay đổi này phản ánh hệ sinh thái JavaScript hiện tại: các runtime luôn được cập nhật, ESM làm nền tảng, việc sử dụng rộng rãi các trình đóng gói và nhu cầu mạnh mẽ về kiểu dữ liệu chính xác và hiệu năng cao.
Nhóm nghiên cứu đã chỉ ra một vài xu hướng tổng quát làm nền tảng cho những quyết định này.ES5 và các trình duyệt thực sự cũ gần như đã biến mất; hệ thống mô-đun AMD/UMD chỉ dành cho một số ít người dùng; hầu hết mọi thứ hiện nay đều được phân phối dưới dạng mô-đun; kiểu dữ liệu nghiêm ngặt là tiêu chuẩn; và hiệu năng phải luôn được ưu tiên hàng đầu, đặc biệt là khi phiên bản 7.0 mang đến khả năng kiểm tra song song.
Do đó, TypeScript 6.0 và 7.0 đang được định hình với các thiết lập mặc định hiện đại và ít "lối thoát lỗi thời" hơn.Đối với phiên bản 6.0 RC, bạn có thể tạm thời tắt các cảnh báo lỗi bằng cách thiết lập... "ignoreDeprecations": "6.0" trong tsconfigNhưng những tùy chọn đó sẽ không còn tồn tại trong phiên bản 7.0. Một số điều chỉnh có thể được tự động hóa bằng các công cụ như công cụ thử nghiệm. ts5to6 codemod, có thể giúp viết lại những thứ như baseUrl và rootDir các cấu hình trên toàn bộ dự án.
Hai điều chỉnh mà nhiều dự án sẽ cần ngay lập tức.
Mặc dù có một danh sách dài các tính năng bị loại bỏ, nhưng hai thay đổi cấu hình có khả năng ảnh hưởng đến số lượng mã nguồn lớn nhất.:
- Đặt rõ ràng
typesmảng (rất thường xuyên)(cộng với khung kiểm thử của bạn). Nếu không có điều này, bạn sẽ mất các kiểu môi trường được tự động bao gồm từ@types/*. - Đặt rõ ràng
rootDir(thông thường"./src") Nếu bạn dựa vào phương pháp "suy luận gốc chung" cũ. Nếu không, cấu trúc tập tin được tạo ra có thể thay đổi theo những cách tinh tế.
Triệu chứng thiếu types bao gồm hàng loạt lỗi liên quan đến các biến toàn cục như... process, fs, path, hoặc là describe không xác địnhCác triệu chứng của sự thay đổi rootDir chủ yếu là về việc các đường dẫn đầu ra bất ngờ nhận được thêm một số thông tin bổ sung. src phân đoạn (ví dụ) dist/src/index.js thay vì dist/index.js).
Cập nhật các thiết lập mặc định cho các dự án hiện đại
Một số tùy chọn trình biên dịch hiện có giá trị mặc định mới phù hợp với cách hầu hết các ứng dụng mới được xây dựng trên thực tế.:
strictbây giờ mặc định làtrueChế độ nghiêm ngặt không còn là một tùy chọn xa xỉ nữa; nó là chế độ mặc định. Nếu trước đây bạn dựa vào chế độ không nghiêm ngặt, bạn sẽ cần phải thiết lập rõ ràng."strict": false(Tuy nhiên, bạn sẽ bỏ lỡ một hạng mục kiểm tra an toàn quan trọng).modulebây giờ mặc định làesnextĐiều này phản ánh rằng ESM là định dạng mô-đun chiếm ưu thế và tương thích tốt nhất với các trình đóng gói và Node hiện đại.targetMặc định là năm ECMAScript hiện tại (hiện tại thực tế là ES2025), thừa nhận rằng hầu hết các triển khai đều nhắm đến môi trường luôn được cập nhật hoặc thông qua một công cụ đóng gói có thể hạ cấp hơn nữa khi thực sự cần thiết.noUncheckedSideEffectImportsbây giờ làtruetheo mặc định, giúp bạn phát hiện lỗi chính tả hoặc đường dẫn sai trong các lệnh nhập khẩu chỉ được thêm vào để tạo hiệu ứng phụ.libReplacementmặc định làfalse, tránh được hàng loạt các lỗi phân giải mô-đun không thành công và chi phí giám sát phát sinh cho đến khi dự án lựa chọn rõ ràng sử dụng các hành vi thư viện chuyên biệt.
Nếu bất kỳ thiết lập mặc định mới nào gây lỗi trong quá trình biên dịch, bạn đều có thể ghi đè chúng một cách rõ ràng. tsconfig.jsonNhưng ý định là các dự án mới nên "tự động làm điều đúng đắn" mà không cần cấu hình thêm.
rootDir Hiện tại, thư mục cấu hình sẽ được sử dụng mặc định.
Trước đây, nếu bạn không chỉ định rootDirTypeScript đã cố gắng suy luận một nguồn gốc chung. Dựa trên tất cả các tệp không phải là tệp khai báo trong chương trình. Điều đó khiến việc xác định ranh giới dự án trở nên khó khăn hơn và đòi hỏi phải quét nhiều đường dẫn tệp chỉ để quyết định vị trí gốc của hàm emit.
Trong TypeScript 6.0, mặc định rootDir đơn giản chỉ là thư mục chứa tsconfig.jsonHành vi suy luận cũ chỉ áp dụng khi bạn chạy. tsc trên dòng lệnh mà không có bất kỳ tsconfig ở tất cả.
Thay đổi này có nghĩa là các dự án có tệp nguồn nằm sâu hơn thư mục cấu hình cần phải thiết lập rõ ràng. rootDirMột cấu hình phổ biến sẽ là:
{
"compilerOptions": {
// ...
"rootDir": "./src"
},
"include":
}
Nếu cấu hình của bạn tham chiếu đến các tệp nằm trên... tsconfig vị trí, bạn cũng cần mở rộng rootDir cho phù hợp, Ví dụ "rootDir": "../src" Dành cho các thư mục nguồn dùng chung.
types hiện mặc định là một mảng rỗng.
Đây có lẽ là thay đổi mang lại tác động lớn nhất đối với các dự án thực tế.Trong lịch sử, nếu bạn không chỉ định types in compilerOptionsTypeScript sẽ tự động bao gồm mọi thứ nằm dưới node_modules/@typesĐiều đó tiện lợi, nhưng cũng tốn kém và dễ hỏng: các kho lưu trữ hiện đại thường thu thập hàng trăm dữ liệu. @types các gói hàng được chuyển tiếp.
Trong TypeScript 6.0, types mặc định là [], có nghĩa là không có gói loại môi trường nào được tải tự động.Giờ đây, bạn có thể lựa chọn tham gia một cách rõ ràng vào các môi trường toàn cầu mà bạn thực sự cần, ví dụ:
{
"compilerOptions": {
"types":
}
}
Điều này có thể giúp giảm 20-50% thời gian xây dựng trong một số dự án., bởi vì trình biên dịch không còn phải duyệt qua từng tệp khai báo nữa. @typesNếu bạn thực sự muốn sử dụng chế độ "tải toàn bộ" như trước đây, bạn có thể chỉ định:
{
"compilerOptions": {
"types":
}
}
Nếu bạn đột nhiên thấy các lỗi như “Không tìm thấy tên 'process'” hoặc “Không tìm thấy mô-đun 'fs'”Đó là tín hiệu để bạn thêm vào. node (và bất kỳ loại kiểm thử/thời gian chạy nào khác mà bạn dựa vào) cho bạn types mảng.
Không được chấp nhận: target: es5 và --downlevelIteration
Việc nhắm mục tiêu ES5 hiện đã lỗi thời.Với việc hầu hết các trình duyệt hiện hành đều hỗ trợ ES2015 trở lên trong nhiều năm và Internet Explorer đã bị loại bỏ, việc xuất ra mã ES5 không còn được coi là đáng để phức tạp hóa vấn đề bên trong TypeScript nữa. Mục tiêu hỗ trợ thấp nhất trong tương lai là ES2015. Nếu bạn thực sự cần phải xuất mã ES5, khuyến nghị là sử dụng trình biên dịch bên ngoài (như Babel hoặc pipeline bundler) trên mã nguồn TS hoặc trên đầu ra của TS.
--downlevelIteration Cờ này cũng đã lỗi thời., bởi vì trường hợp sử dụng có ý nghĩa duy nhất của nó là điều chỉnh hành vi phát ra cho các mục tiêu ES5. Trong TypeScript 6.0, thiết lập downlevelIteration Việc sử dụng cờ này sẽ gây ra lỗi cảnh báo lỗi thời. Nếu bạn đang dùng ES2015 trở lên, cờ này vốn dĩ không có tác dụng gì.
Không được chấp nhận: --moduleResolution node và di sản classic
node (Aka node10Chế độ phân giải mô-đun đã lỗi thời.Nó mô phỏng hành vi của Node 10 nhưng không phù hợp với ESM và ngữ nghĩa phân giải của Node hiện đại. Các dự án nên chuyển sang một trong hai cách sau: nodenext (đối với các mục tiêu Node trực tiếp) hoặc bundler (dành cho môi trường được điều khiển bởi trình đóng gói như ứng dụng web hoặc Bun).
Bản gốc moduleResolution: classic Chiến lược này cũng đã bị loại bỏ.Đây là câu chuyện về cơ chế phân giải trước khi có Node của TypeScript. Ngày nay, tất cả các trường hợp thực tế đều được giải quyết tốt hơn bởi... nodenext or bundlerVì vậy, phiên bản cổ điển đã bị loại bỏ để giảm độ phức tạp và các trường hợp ngoại lệ.
Đã lỗi thời: AMD, UMD, SystemJS và module: none
Sau đây module Các giá trị này hiện đã lỗi thời và không còn được hỗ trợ.:
amdumdsystemjsnone
Các định dạng này rất quan trọng trong thời kỳ trước ESM.Vào thời điểm đó, các trình duyệt thiếu hỗ trợ mô-đun gốc và các nhà phát triển phải dựa vào AMD, UMD hoặc SystemJS để lấp đầy khoảng trống. Ngày nay, ESM cùng với các trình đóng gói hoặc bản đồ nhập khẩu xử lý hầu hết các trường hợp sử dụng thực tế, và khái niệm "không có" chưa bao giờ được định nghĩa rõ ràng.
Nếu bạn vẫn đang nhắm đến các định dạng mô-đun cũ nàyTheo khuyến nghị, nên chuyển sang mục tiêu phát ra mã ESM và dựa vào trình đóng gói hoặc trình biên dịch thay thế để đóng gói cuối cùng — hoặc tiếp tục sử dụng TypeScript 5.x cho đến khi có kế hoạch chuyển đổi. Là một phần của quá trình dọn dẹp này, hệ thống cũ cũng được nâng cấp. amd-module Chỉ thị này cũng bị bãi bỏ.
Không được chấp nhận: baseUrl
baseUrl Tùy chọn này từ lâu đã là nguồn gốc của các hành vi phân giải mô-đun kỳ lạ và khó gỡ lỗi.Nhiều dự án chỉ sử dụng nó như một tiền tố. paths các mục nhập, nhưng TypeScript cũng coi nó như một thư mục gốc tra cứu chung, gây ra các lỗi nhập khẩu như "someModule" giải quyết src/someModule.js Thật bất ngờ, trong khi ý định của nhà phát triển chỉ là hỗ trợ các bí danh tùy chỉnh như... @app/*.
Song song với sự tăng trưởng vượt xa mong đợi của baseUrl đã lỗi thời và sẽ không còn được sử dụng làm gốc tra cứu nữa.Việc lập bản đồ đường dẫn không yêu cầu baseUrl đã khá lâu rồi, vì vậy phương án chuyển đổi được khuyến nghị đơn giản là gộp tiền tố vào từng phần. paths mục nhập. Ví dụ:
// Before
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@app/*": ,
"@lib/*":
}
}
}
// After
{
"compilerOptions": {
"paths": {
"@app/*": ,
"@lib/*":
}
}
}
Chỉ trong những trường hợp hiếm hoi mà bạn thực sự đã sử dụng baseUrl như một gốc tra cứu chung Bạn có cần tái tạo hành vi đó bằng cách sử dụng ánh xạ đường dẫn bao quát như sau không:
"paths": {
"*": ,
"@app/*": ,
"@lib/*":
}
Đối với hầu hết các đội, chỉ cần loại bỏ baseUrl và chèn tiền tố vào trong paths sẽ rõ ràng và an toàn hơn.
Khả năng tương tác và tính nghiêm ngặt: esModuleInterop, allowSyntheticDefaultImportsvà alwaysStrict
TypeScript 6.0 cũng duy trì hành vi tương tác mặc định được khuyến nghị từ lâu.Bạn không thể thiết lập nữa. esModuleInterop or allowSyntheticDefaultImports đến falseBan đầu, các tùy chọn này được thiết kế để người dùng tự chọn bật/tắt nhằm tránh làm hỏng các dự án cũ, nhưng việc tắt chúng hiện nay thường dẫn đến các sự cố nhỏ trong quá trình chạy khi kết hợp CommonJS và ESM.
Khi tính năng tương tác luôn được bật, một số mẫu nhập khẩu có thể cần được cập nhật.. Ví dụ:
// Old style with esModuleInterop: false
import * as express from "express";
// New style with modern interop always on
import express from "express";
alwaysStrict cờ cũng không thể được đặt thành false nữa khôngTypeScript hiện giả định ngữ nghĩa của chế độ nghiêm ngặt JavaScript trên mọi phương diện, bao gồm cả cách các từ khóa dành riêng và this Hãy cư xử cho đúng mực. Nếu bạn có đoạn mã thực sự cũ sử dụng các từ khóa dành riêng như... await or static Vì chúng là các mã định danh, bạn cần phải đổi tên chúng.
Không được chấp nhận: outFile, không gian tên cũ module từ khóa và nhập khẩu asserts
--outFile Tùy chọn này đã bị loại bỏ trong phiên bản 6.0.Việc ghép nhiều đầu vào thành một gói JavaScript duy nhất là công việc tốt hơn nên được xử lý bởi Webpack, Rollup, esbuild, Vite, Parcel hoặc các công cụ tương tự. TypeScript đang tập trung mạnh vào kiểm tra kiểu và phát ra khai báo thay vì cố gắng trở thành một công cụ đóng gói.
Việc sử dụng kế thừa của module Việc khai báo không gian tên hiện là một lỗi nghiêm trọng.Phiên bản TypeScript ban đầu cho phép:
module Foo {
export const bar = 10;
}
Cú pháp hiện đại, được hỗ trợ sử dụng namespace:
namespace Foo {
export const bar = 10;
}
Thay đổi này là cần thiết để tránh xung đột với ECMAScript có thể có trong tương lai. module khốiCác khai báo mô-đun môi trường như declare module "some-module" { ... } Vẫn được hỗ trợ đầy đủ.
Nhập các khẳng định bằng cách sử dụng asserts cũng đã lỗi thời, bởi vì đề xuất cơ bản đã phát triển thành các thuộc tính nhập khẩu bằng cách sử dụng withĐoạn mã như sau:
import blob from "./data.json" asserts { type: "json" };
Nên được chuyển đổi sang biểu mẫu mới.:
import blob from "./data.json" with { type: "json" };
Không được chấp nhận: no-default-lib Danh sách tham chiếu và tệp dòng lệnh với tsconfig
/// <reference no-default-lib="true" /> Chỉ thị này không còn được hỗ trợ nữa.Điều này thường bị hiểu sai. Nếu bạn cần loại trừ thư viện mặc định, hãy sử dụng... --noLib or --libReplacement Thay vào đó, chúng thể hiện rõ hơn ý định ở cấp độ cấu hình.
Một nguồn gây nhầm lẫn lâu nay khác là làm thế nào tsc xử lý các đối số tệp rõ ràng khi tsconfig.json là quà tặngTrước đây, khi chạy tsc foo.ts Trong thư mục như vậy, tệp cấu hình sẽ bị bỏ qua một cách âm thầm. Trong phiên bản 6.0, trường hợp đó sẽ tạo ra lỗi rõ ràng:
error TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.
Nếu bạn thực sự muốn bỏ qua bước cấu hình và chỉ biên dịch một tệp duy nhất với các giá trị mặc định, bây giờ bạn có thể sử dụng tsc --ignoreConfig foo.ts Để làm rõ ý định đó.
Chuẩn bị cho TypeScript 7.0
TypeScript 6.0 đã hoàn thiện về tính năng và hầu hết đang trong giai đoạn ổn định.Từ đây đến khi phát hành rộng rãi, nhóm dự kiến chỉ cần sửa các lỗi nghiêm trọng. Các bản dựng hàng đêm được phát hành thường xuyên, và nhóm cũng phát hành các phiên bản hàng đêm của TypeScript 7.0 (dựa trên Go) sắp ra mắt cùng với một tiện ích mở rộng VS Code chuyên dụng để thử nghiệm với công cụ mới.
Lộ trình được thiết kế khá chặt chẽ: phiên bản 7.0 dự kiến sẽ ra mắt ngay sau phiên bản 6.0.Vì vậy, chu kỳ phản hồi về những khó khăn khi nâng cấp và các vấn đề di chuyển sẽ ngắn. Nếu bạn thấy cảnh báo lỗi thời trong phiên bản 6.0, chúng tôi đặc biệt khuyên bạn nên giải quyết chúng ngay bây giờ thay vì chờ đến khi phiên bản 7.0 buộc bạn phải làm vậy.
Quy trình làm việc thực tế của hầu hết các nhóm trông như thế này:Hãy nâng cấp lên TypeScript 6.0 RC để sửa lỗi. types và rootDir, xử lý các vấn đề lỗi thời (hoặc tạm thời hạn chế chúng) "ignoreDeprecations": "6.0" trong khi bạn lặp lại), và chạy với --stableTypeOrdering Nếu bạn cần so sánh kết quả đầu ra hoặc chuẩn bị các pipeline CI cho thứ tự xác định của phiên bản 7.0. Sau khi thiết lập xong, việc chuyển sang trình biên dịch dựa trên Go sẽ mang lại cảm giác nâng cấp hiệu năng hơn là một sự thay đổi gây gián đoạn.
Nhìn chung, TypeScript 6.0 RC không chú trọng nhiều đến cú pháp bóng bẩy mà tập trung vào việc thiết lập nền tảng.Tốc độ xử lý gốc trong phiên bản 7.0, cấu hình gọn gàng hơn, các thiết lập mặc định hiện đại và các API được chuẩn hóa như Temporal và các hàm tích hợp ES2025 giúp việc lập trình hàng ngày dễ dàng hơn. Nếu bạn áp dụng nó ngay bây giờ, khắc phục các lỗi nhỏ và tận dụng các thiết lập mặc định mới, bạn sẽ có vị thế tốt hơn nhiều khi trình biên dịch gốc ra mắt.
