现象
在某个node项目中,其ts的语法检查速度过慢,改完变量类型后需要几秒钟的时间才能给到反馈
问题排查
环境
版本信息
-----------------
系统: macOS Big Sur v11.5.2
tsc: v4.5.2
node: v14.17.0
使用ts性能分析工具 Performance Tracing 找出 hot spot.
step1. 执行tsc生成tace文件,可以观察到如下的错误信息
$tsc --generateTrace ./trace
app/model/demo.ts:30:17 - error TS2321: Excessive stack depth comparing types 'Model<?, TQueryHelpers, TMethods>' and 'Model<?, TQueryHelpers, TMethods>'.
30 const model = db.model<Demo>('Demo', DemoSchema);
step2. 在浏览器输入 about://~~~~tracing~~~~ (或者打开浏览器控制面板的Performance - 推荐用这种方式),上传trace文件夹下的trace.json文件
可以看出,TS在处理app/model/demo.ts 文件用时长达2s+,其代码如下:
import { Mongoose } from 'mongoose';
interface Demo {
apiId: string;
accountId: string;
}
export default (mongoose: Mongoose.Mongoose, db: Mongoose.Connection) => {
const { Schema } = mongoose;
const DemoSchema = new Schema<Demo>({
apiId: String,
accountId: String
})
const model = db.model<Demo>('Demo', DecmoSchema);
return model;
}
这个问题的表面原因是由于TS做类型推断出陷入了无限循环,github上有相关的issue#46989
解决方案
降级到4.4.3
- 对model手动添加类型
export default (mongoose: Mongoose.Mongoose, db: Mongoose.Connection) => {
- const model = db.model<Demo>('Demo', DemoSchema);
+ const model: Mongoose.Model<Demo> = db.model<Demo>('Demo', DemoSchema);
}
- 安装vscode插件 JavaScript and TypeScript Nightly extension,提供了最新版的typescript来替代vscode内置的typescript版本(无需调整代码)
Deep(WIP)
debug下ts陷入嵌套的原因
Example : github.com/microsoft/T…
Typescript更新
Typescript在v4.5版本中发布了Feature: Tail-Recurison Elimination on Conditional Types
大概的意思是说,之前的版本中在检查到可能是无限递归的情况时会直接报错,这个版本会消除某些情况下的尾递归来避免这种问题。
这里涉及到的概念
其中类型重载也是一种条件类型,Model.model这个就是类型重载
model<T>(name: string, schema?: Schema<T>, collection?: string): Model<T>;
model<T, U extends Model<T, TQueryHelpers, any>, TQueryHelpers = {}>(
name: string,
schema?: Schema<T, U, TQueryHelpers>,
collection?: string,
skipInit?: boolean
): U;
- 尾递归:一个函数返回该函数本身的调用值的递归情况
阅读文档
- Typescript性能优化指南 github.com/microsoft/T…