如何分享自己项目/包的 类型定义 给第三方使用?

2022-05-09 09:01:48 +08:00
 yazoox

现在有一个第三方的脚本,比如 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 包分享给第三方。

1341 次点击
所在节点    JavaScript
9 条回复
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 中的类型
yazoox
2022-05-09 15:00:59 +08:00
@Envov 兄弟,谢谢先。
```
import type (someTypes) from "@types/mypackage"
```
这个给了我很大的提示。
p.s.
不过,看你的描述,好像是我们在使用 3rdparyty 的 types
我们的需求是,我们提供 types ,3rdparty.js 使用我们提供的 types
Envov
2022-05-09 15:09:02 +08:00
@yazoox 是的,上面的步骤就是在项目中描述 3rdparty.js 的类型,一句话就是把自己写的类型发布到 "@types/mypackage" 然后在项目里面把 3rdparty.js 的类型链接到"@types/mypackage"
yazoox
2022-05-09 17:12:52 +08:00
@Envov thx.
这一句是啥意思,主要是这个 Thirdpary ?这里没有一个项目或者文件叫 Thirdpary 呢。
```
"globals": {
"Thirdparty": "writable"
},
```
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 或者$符号类似
yazoox
2022-05-09 18:12:06 +08:00
@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(...);
}

```
Envov
2022-05-09 18:59:57 +08:00
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=>{/** 这里就获得了类型提示 */})
yazoox
2022-05-10 09:08:44 +08:00
@Envov
不过,为什么你要 declare 并且 import 这个 jquery 的 js 地址呢?( https://code.jquery.com/jquery-3.6.0.js)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851643

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX