TypeScript 5.1 在 5.0 釋出後不久就釋出了測試版,但測試版不代表最終正式版。
官方原文 Announcing TypeScript 5.1 Beta 中提供了完整的更新內容,以下是我梳理的 TypeScript 5.1 主要更新內容:
- 改進了函式返回值型別
undefined
的型別推斷 Getter
和Setter
現在支援設定不同的型別- 自動補全 JSDoc
@param
標籤的程式碼片段 - TypeScript 5.1 至少需要執行在
ES2020
和Node.js 14.17
的執行時環境中
想要嚐鮮的朋友,可以透過 npm 快速安裝最新測試版:
npm install -D typescript@beta
1. 改進函式返回值型別 undefined 的型別推斷
在 JavaScript 中,函式如果沒有返回值,會自動返回 undefined
。
// no return
const test = () => {}
test(); // undefined
在早期版本的 TypeScript 中,只有返回值型別為 void
和 any
的函式可以沒有 return
語句,即使你清楚這個函式返回值是 undefined
,你也需要至少有一個 return
語句。
// ✅ return 'void'
const t1 = () => {}
// ✅ 'void' doesn't need a return statement
const t2 = (): void => {}
// ✅ 'any' doesn't need a return statement
const t3 = (): any => {}
// ❌ A function whose declared type is neither 'void' nor 'any' must return a value.
const t4 = (): undefined => {}
當你希望函式返回 undefined
,你可以有 2 種方式:
- 使用
return undefined
語句; - 使用
return
語句並且定義返回值型別為undefined
。
declare function fun(f: () => undefined): undefined;
// ❌ Argument of type '() => void' is not assignable to parameter of type '() => undefined'.
fun(() => {})
// ❌ A function whose declared type is neither 'void' nor 'any' must return a value.
fun((): undefined => {})
// ❌ Argument of type '() => void' is not assignable to parameter of type '() => undefined'.
fun(() => {
return;
})
// ✅
fun(() => {
return undefined;
});
// ✅
fun((): undefined => {
return;
});
為了解決這種困惑,TypeScript 5.1 支援允許函式返回 undefined
時不需要 return
語句。
// ✅ TypeScript 5.1!
const f1 = (): undefined => {}
// ✅ TypeScript 5.1!
f2((): undefined => {})
2. Getter 和 Setter 支援設定不同型別
在 TypeScript 4.3 允許為 Getter
和 Setter
指定不同型別。
interface Serializer {
set value(v: string | number | boolean);
get value(): string;
}
declare let box: Serializer;
// ✅ Allows writing a 'boolean'
box.value = true;
// ✅ Comes out as a 'string'
console.log(box.value.toUpperCase());
// ❌ Property 'toFixed' does not exist on type 'string'.
console.log(box.value.toFixed());
最初,我們要求 get
型別必須是 set
型別的子型別,這種寫法很有效。
box.value = box.value;
但是,很多現有 API 的 Getter
和 Setter
之間存在完全不相關的型別。例如,DOM 和 CSSStyleRule
API 中的 style 屬性。每個樣式規則都有一個 CSSStyleDeclaration
型別的 style
屬性,但你只能使用字串修改它。
TypeScript 5.1 支援為 Getter
和 Setter
設定不同型別:
interface CSSStyleRule {
// ...
/** Always reads as a `CSSStyleDeclaration` */
get style(): CSSStyleDeclaration;
/** Can only write a `string` here. */
set style(newValue: string);
// ...
}
也支援下面這樣使用:
class SafeBox {
#value: string | undefined;
// Only accepts strings!
set value(newValue: string) {}
// Must check for 'undefined'!
get value(): string | undefined {
return this.#value;
}
}
實際上,這類似於在 --exactOptionalProperties
下檢查可選屬性的方式。
3. 自動補全 JSDoc @param 標籤的程式碼片段
TypeScript 5.1 支援在 TypeScript 和 JavaScript 檔案中輸入 @param 標記時的程式碼片段完成。幫助我們在編寫程式碼文件或在 JavaScript 中新增 JSDoc 型別時快速生成對應註釋資訊。
4. 最低執行時要求:ES2020 和 Node.js 14.17
TypeScript 5.1 支援 ECMAScript 2020 新特性,因此需要在較新的 Node.js 執行環境下使用,至少需要 Node.js 14.17 版本以上。舊版 Node.js 可能導致 tsc.js
或 tsserver.js
執行錯誤。
node_modules/typescript/lib/tsserver.js:2406
for (let i = startIndex ?? 0; i < array.length; i++) {
^
SyntaxError: Unexpected token '?'
at wrapSafe (internal/modules/cjs/loader.js:915:16)
at Module._compile (internal/modules/cjs/loader.js:963:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
總結
TypeScript 5.1 目前還在測試階段,預計會在接下來的幾周內釋出候選版本和最終穩定版本。如果你對 TpeScript 感興趣,可以安裝測試版嘗試體驗一下。