有如下结构
我们有一个JS库hi,位于src/lib
,这是一个非常原始基于原型链的类,内容如下,
function Hi(name) {
this.name = name;
return this;
}
Hi.prototype.sayHi = function () {
console.log('Hi ' + this.name);
}
Hi.Zero = 0;
当我们需要在index.ts中使用hi.js 需要做下面步骤
- 改造
hi.js
导出public内容。 - 开启tsconfig.js 允许编译js文件
- 引用
hi.js
。 - [可选] 友好的代码提示。
在原hi.js文件末尾加上导出函数
function Hi(name) {
this.name = name;
return this;
}
Hi.prototype.sayHi = function () {
console.log('Hi ' + this.name);
}
Hi.Zero = 0;
export { Hi };
编辑 tsconfig.js 文件加入 "allowJs": true
,内容如下:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./lib",
"strict": true,
"lib": ["es6","dom"],
"allowJs": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
这样ts在编译后才会将目录中js文件编译到输出目录。
在配置后立刻使用编译命令
npm run build
可以发现lib/
目录内除了原来的index.js还多了./lib/lib/hi.js
、./lib/lib/hi.js.ts
点开 lib/lib/hi.js.ts 还可以看到ts帮我们分析生成hi.d.ts
为了能够在index中调用到hi.js
,我们需要在index.ts中导入 ./lib/hi
(省略后缀.js
)
导入格式为:src下的相对路径省略js后缀 。
index.ts 内容如下
import {Hi} from './lib/hi';
let a = new Hi('world');
a.sayHi();
再次编译代码可以看到index.ts 导入了./lib/hi.js
,然后运行
npm run build
运行程序检验导入是否成功
node ./lib/index.js
可以看到执行结果满足预期,若点开lib/index.js
可以看到通道quire导入了hi的库文件。
就算我们不编写hi.d.ts
TypeScript在编译后也会我们的Js模块生成 .d.ts 但是类型都是any
这样无法复用ts的类型推断,我们可以基于生成的 .d.ts
文件优化其参数满足我们的推断要求。
在库文件的同级目录下创建与库文件一致的文件名但后缀为.d.ts
.d.ts
文件可从编译后生成d.ts进行修改,也可手工编写。
例如 hi.js 与 hi.d.ts,hi.d.ts 内容 如下:
export class Hi {
constructor(name: string);
name: string;
sayHi(): void;
static readonly Zero: number;
}
编写完成后我们再次回到 index.ts
文件中编写,可以看到VSCode已经能够根据类型进行推断给与提示。
再次编译运行
npm run build
node ./lib/index.js