JS项目用TypeScript做类型辅助:避免仅为类型导出变量的方案
问题
我有一个JavaScript项目,仅将TypeScript作为类型辅助工具使用,暂无全量迁移至TypeScript的计划。
在index.js文件中定义了varA和varB两个变量,它们在该文件中被赋值后,会作为参数传入其他文件的函数中。我希望为这些其他文件中的函数添加类型约束,且这些函数均具有相同的接口。
目前我的做法是创建一个类型声明文件,在其中定义通用接口并通过JSDoc标注到各个函数文件中。我不想手动定义varA和varB的类型,希望复用index.js中自动推断出的类型。当前可行的方案是将这两个变量显式导出,再在声明文件中导入以获取类型,但这些变量仅为类型用途导出,并未在其他文件中直接使用,请问是否有更优的替代方案?
现有代码示例
// index.js const varA = getConfigVar(..., 'a'); const varB = getConfigVar(..., 'b'); //... do something if(something) { funA(varA, varB); } else { funB(varA, varB); } // 仅为获取类型而导出 module.exports = { varA, varB, }
// funA.js /** @type {Func} */ function funA(a, b) { // ... }
// funB.js /** @type {Func} */ function funB(a, b) { // ... }
// types.d.ts interface Func { (a: typeof import('./index').varA, b: typeof import('./index').varB): void }
优化方案
方法1:在index.js中用JSDoc定义类型别名(无需导出变量)
直接在变量所在文件通过JSDoc生成类型别名,TypeScript会自动复用变量的推断类型,无需导出实际变量:
修改index.js添加类型别名定义:
// index.js const varA = getConfigVar(..., 'a'); const varB = getConfigVar(..., 'b'); /** * @typedef {typeof varA} VarAType * @typedef {typeof varB} VarBType * @typedef {(a: VarAType, b: VarBType) => void} FuncType */ //... do something if(something) { funA(varA, varB); } else { funB(varA, varB); } // 不再需要为类型导出varA、varB
在函数文件中直接引用该类型别名:
// funA.js /** @type {import('./index').FuncType} */ function funA(a, b) { // ... }
// funB.js /** @type {import('./index').FuncType} */ function funB(a, b) { // ... }
方法2:用import type在类型声明文件中仅导入类型(TS 3.8+)
保留单独的类型声明文件,通过import type仅导入变量的类型信息,不引入实际变量,同时用JSDoc标记变量供类型系统识别:
修改index.js,添加@export标记(仅用于类型系统,不影响运行时导出):
// index.js /** @export */ const varA = getConfigVar(..., 'a'); /** @export */ const varB = getConfigVar(..., 'b'); //... do something if(something) { funA(varA, varB); } else { funB(varA, varB); } // 不需要实际导出变量
更新types.d.ts使用import type:
// types.d.ts import type { varA, varB } from './index'; interface Func { (a: typeof varA, b: typeof varB): void }
方法3:直接在函数JSDoc中引用变量类型
无需单独类型文件,直接在函数的JSDoc里通过import()获取变量的推断类型:
// funA.js /** @type {(a: typeof import('./index').varA, b: typeof import('./index').varB) => void} */ function funA(a, b) { // ... }
同样需要在index.js中给varA和varB添加@export标记,让TypeScript的类型系统能识别到它们。
内容的提问来源于stack exchange,提问作者gaurav5430
相关产品推荐
相关产品推荐

