现在有一个第三方的脚本,比如 https://www.sample.com/files/3rdparty.js ,我们需要动态的下载并运行它。已经定义好,该脚本有一个 entryPoint 方法,我们调用它的时候,会传一个定义好的 object/instance 进去。
e.g. 3rdparty.js
entryPoint(obj) {
const db = obj.getDatabase();
if (db) {
// ...
}
}
但现在,这个第三方的脚本,想用 Typescript 写,希望使用我们的 type definition
我想了想,直接发一个 @types/mypackage 好像不行,因为需要在 3rdpary.js 里面 import * as a from "mypackage" 才能够自动匹配找到 @types/mypackage ,而第三方,并不需要 import 我们的 mypackage
这个情况下,我们要怎么分享我们的类型定义给他们?
p.s.
我们现在做的,就是把所有的 interface 放到一个文件里面,比如 interface.ts ,然后把这个文件做成一个新的包,mypackage-common ,然后我们自己的 mypacakge 里面 import * as a from "mypackage-comm",再把这个 mypackage-common 包分享给第三方。
1
Envov 2022-05-09 14:54:41 +08:00
1 、首先在你的 tsconfig.json 定义 d.ts 的路径,目的是让编辑器读取自定义的类型声明文件
{ "compilerOptions": { "typeRoots": [ "./your-types-path", "./node_modules/@types"] } } 2 、在你的 types 文件夹中建立一个 d.ts 文件,例如 your-types-path/3rdparty-types.d.ts 3 、在该 d.ts 文件中声明 https://www.sample.com/files/3rdparty.js 这个脚本的类型,你可以先将类型发布到 npm 然后在这里引入申明 import type {someTypes} from "@types/mypackage" declare global { namespace Thirdparty { const entryPoint: someTypes; } } 4 、如果你配置了 eslint ,还需要在 eslint 编辑全局变量的类型 .eslintrc "globals": { "Thirdparty": "writable" }, 5 、你现在可以在任何地方写 Thirdparty.entryPoint 它追踪 @types/mypackage 中的类型 |
2
yazoox OP @Envov 兄弟,谢谢先。
``` import type (someTypes) from "@types/mypackage" ``` 这个给了我很大的提示。 p.s. 不过,看你的描述,好像是我们在使用 3rdparyty 的 types 我们的需求是,我们提供 types ,3rdparty.js 使用我们提供的 types |
3
Envov 2022-05-09 15:09:02 +08:00
@yazoox 是的,上面的步骤就是在项目中描述 3rdparty.js 的类型,一句话就是把自己写的类型发布到 "@types/mypackage" 然后在项目里面把 3rdparty.js 的类型链接到"@types/mypackage"
|
4
yazoox OP @Envov thx.
这一句是啥意思,主要是这个 Thirdpary ?这里没有一个项目或者文件叫 Thirdpary 呢。 ``` "globals": { "Thirdparty": "writable" }, ``` |
5
Envov 2022-05-09 17:29:47 +08:00
@yazoox 目的是在全局中使用 Thirdparty 变量不报错,这个名字你可以随便取,表示的是 https://www.sample.com/files/3rdparty.js 这个 js 中使用的 window 下的命名空间,https://www.sample.com/files/3rdparty.js 不是通过 script 引入的吗和 jquery 或者$符号类似
|
6
yazoox OP @Envov
所以, ``` declare global { namespace Thirdparty { const entryPoint: someTypes; } } ``` 是和 ``` "globals": { "Thirdparty": "writable" }, ``` 配套的 不过,我的 entryPoint 不是挂在 window 下面的(或者说,Thirdpary 不是挂在 window 下面的)是 dynamic import 直接下载然后引用方法的。e.g. ``` export async function loadJS(url: string) { const actions = await import(/* webpackIgnore: true */ url); return actions; } ... const module = await loadJS("https://www.sample.com/files/3rdparty.js"); if (module.entryPoint) { module.entryPoint(...); } ``` |
7
Envov 2022-05-09 18:59:57 +08:00
![image-20220509185834967]( https://s2.loli.net/2022/05/09/CqEca8KpPLWuiSF.png)
![image-20220509185902482]( https://s2.loli.net/2022/05/09/FX9kWJ6mtHPoBzn.png) ![image-20220509185941384]( https://s2.loli.net/2022/05/09/tbBNnyg2QDJ3Az5.png) |
8
Envov 2022-05-09 19:12:40 +08:00
npm install envov-test-types --save-dev
在 ts 文件中写这个: import "envov-test-types" import('https://code.jquery.com/jquery-3.6.0.js').then(module=>{/** 这里就获得了类型提示 */}) |
9
yazoox OP |