一、独立声明文件(Isolated Declarations):提升代码模块化和可维护性
TypeScript 5.5 引入了独立声明文件的概念,让开发者可以编写独立编译和验证的声明文件(.d.ts 文件),无需依赖完整的源代码。这一特性使得代码更加模块化和易于维护,尤其适合大型项目。
二、类型谓词推断:更精确的类型检查
TypeScript 5.5 增强了类型谓词推断功能,让代码的类型检查更为精确。来看一个例子:
function makeBirdCalls(countries: string[]) {
// birds: Bird[]
const birds = countries
.map(country => nationalBirds.get(country))
.filter(bird => bird !== undefined);
for (const bird of birds) {
bird.sing(); // ok!
}
}
在这个例子中,TypeScript 通过推断过滤函数的类型谓词,知道 bird !== undefined 意味着 bird 是 Bird 类型。我们可以将其拆分为独立函数,更清晰地看到这一过程:
// function isBirdReal(bird: Bird | undefined): bird is Bird
function isBirdReal(bird: Bird | undefined) {
return bird !== undefined;
}
bird is Bird 是类型谓词,表示如果函数返回 true,那么 bird 是 Bird 类型;如果返回 false,则 bird 是 undefined。这种类型谓词使得过滤后的 birds 数组类型更加精确,代码通过类型检查。
三、正则表达式检查:增强代码检查能力
之前的 TypeScript 版本通常会跳过大部分正则表达式的检查,因为正则表达式的语法具有可扩展性,而 TypeScript 并没有尝试将正则表达式编译成早期版本的 JavaScript。TypeScript 5.5 引入了对正则表达式的更深入检查,提高了代码的可靠性。
基本语法检查
现在,TypeScript 可以捕捉到一些常见的正则表达式错误。例如:
let myRegex = /@robot(\s+(please|immediately)))? do some task/;
// ~
// error!
// Unexpected ')'. Did you mean to escape it with backslash?
在上面的例子中,TypeScript 识别到了一个意外的右括号,并提示开发者是否需要使用反斜杠来转义它。这种简单的检查可以捕捉到许多常见的错误。
捕捉回溯引用问题
TypeScript 5.5 的检查不仅限于语法错误,还可以捕捉不存在的回溯引用问题。例如:
let myRegex = /@typedef \{import\((.+)\)\.([a-zA-Z_]+)\} \3/u;
// ~
// error!
// This backreference refers to a group that does not exist.
// There are only 2 capturing groups in this regular expression.
在上面的例子中,正则表达式只有两个捕获组,但尝试引用第三个组时,TypeScript 会提示错误。
命名捕获组检查
同样地,TypeScript 也能检查命名捕获组的错误:
let myRegex = /@typedef \{import\((?<importPath>.+)\)\.(?<importedEntity>[a-zA-Z_]+)\} \k<namedImport>/;
// ~~~~~~~~~~~
// error!
// There is no capturing group named 'namedImport' in this regular expression.
在上面的正则表达式中,namedImport 捕获组并不存在,TypeScript 会提示相应的错误。
ECMAScript 版本检查
此外,TypeScript 还会根据目标 ECMAScript 版本,检查正则表达式中使用的特性。例如,如果在目标为 ES5 的环境中使用了命名捕获组,会提示错误:
let myRegex = /@typedef \{import\((?<importPath>.+)\)\.(?<importedEntity>[a-zA-Z_]+)\} \k<importedEntity>/;
// ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
// error!
// Named capturing groups are only available when targeting 'ES2018' or later.
同样,对于某些正则表达式标志,TypeScript 也会进行相应的检查。
四、configDir 变量:更灵活的配置文件
在 TypeScript 5.5 中,当在 tsconfig.json 或 jsconfig.json 文件的某些路径字段中写入 ${configDir} 时,这个变量会被替换为配置文件所在的目录。例如,我们可以这样重写 tsconfig.base.json 文件:
{
"compilerOptions": {
"typeRoots": [
"${configDir}/node_modules/@types",
"${configDir}/custom-types"
],
"outDir": "${configDir}/dist"
}
}
这样,当项目继承这个配置文件时,路径将相对于派生的 tsconfig.json 文件,而不是共享的 tsconfig.base.json 文件。这使得配置文件更易于跨项目共享,也确保了配置文件的可移植性。如果你打算让 tsconfig.json 文件可扩展,考虑使用 ${configDir} 代替 ./。
结束
这些新特性使得 TypeScript 5.5 在模块化、精确性和灵活性方面都有了显著提升,更适合现代开发需求。如果你想了解更多详细信息,可以访问 TypeScript 官方博客。https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/