公共模块,通常会被多个项目、不同的开发人员使用,所以开发公共模块时,你自己会用还不够,要让所有人都能很快的知道怎么去使用,这一点很关键。通常会从3个方面做到这点:

  1. 精心分割代码逻辑,遵循开闭原则;
  2. 变量名采用自解释性的标识符;
  3. 依赖完善的使用提示。

第1点用户体验不到,如果没有做好第3点,第2点用户也是体验不到的,只有第3点时真正面对用户的,所以做好第3点很重要!本篇文章就是教你如何在实现js模块时,做好完善的使用提示。

是否要用ts写公共项目?

目前不建议使用ts开发公共组件,理由如下:

你的项目正常应该是打包成 umd包,并且和源码一起发布。因为:

umd包使用非常灵活,支持script标签隐式引用,amd,cmd,commonjs,esm引用,也是当前最流行的公共模块包。但umd包不能使用tree-shaking。
tree-shaking作为官方的项目优化方案,目前越来越流行,几乎已是必备的项目优化技术。tree-shaking是基于es module的,单纯的umd无法实现。
通常恰好你的公共模块源码就是通过es module编写的,所以将源码一起发布,不只是让使用者能够查看,还为了让使用者方便tree-shaking优化。

如果业务项目(这里指 引用你的公共项目模块的其他项目,以下都是这个意思)不会用到源码,只是引用umd包,那么采用ts编写源码不会有任何影响。
但如果要做tree-shaking而引用源码时,而你的源码是用ts编写,问题就来了:业务项目无形中被绑上了ts的“贼船”,引用你的源码,同时打包编译脚本要支持ts。
如果业务项目不想引入ts怎么办?

ts的很多优点,但的确不太适合开发公共项目,而且运用js Doc 注释,ts的绝大多数有点也能轻松实现。
而且即便业务项目使用ts开发,也能引用你的js模块。

为了不给业务项目带来副作用,就采用js语言吧。

js中使用ts

尽管确定使用 js语言编写公共项目,你依然享受到 ts的便利。ts天生就支持js!

// @ts-check
// js文件开头,使用上面这个注释,开启ts支持。接下来整个文件,都有了ts校验的功能,会出现类型错误提示等。 let a = 22
// @ts-ignore
a="string" // 将一个string赋给number类型的a,正常情况会有类型报错。但
// 上一行 // @ts-ignore 这个注释表示,接下来的一条语句忽略ts校验,所以这里不报错

开启 ts 校验后,接下来就使用 jsDoc了,如果你还安装了typeScript:

#全局安装:
npm install -g typescript #或 项目局部安装:
npm install --save-dev typescript

那么接下来,使用命令 :  tsc --declaration src/lib/service.js --allowJs   就可以根据你所写的 JSDoc,为你的service.js文件生成 .d.ts文件了。

转换的示例(下方示例的js代码生成的.d.ts):

export type MethodType = "get" | "post" | "delete" | "put" | "patch";
export type RequesFn = (method: MethodType, url: string, params: any) => Promise<object>;
export type Person = {
name: string;
age: number;
sex: 'male' | 'female';
};
export type AxiosRes<T> = {
code: number;
data: T;
msg: string;
}; export type TokenRes = {
mediaId: string;
mediaKey: string;
token: string;
};

JSDoc示例

1、定义复杂类型+对变量添加类型

// @ts-check

/**
* @typedef {{name:string,age:number,sex:'male'|'female'}} Person
*/
/**
* @type Person
*/
let jim = {name:'jim',age:28,sex:'female'}

把鼠标移到 jim变量上,还有类型提示,就像ts中一样:

关于类型提示的示例截图,接下来就不贴上了,你可以在 vscode 试一下。

2、函数的类型

/**
* @typedef {'get'|'post'|'delete'|'put'|'patch'} MethodType
*/
/**
* @returns { Promise<object>} // 定义返回的类型
* @param {MethodType} method // 注意是@param,不再是@type了,MethodType是前面定义好的类型
* @param {string} url
* @param {*} [params] // 中括号表示可选参数,*表示any类型
*/
function myAjax(method,url,params){
return new Promise(resolve=>{
// other code ...
})
}

js里也有类型推断,如果不指明返回的是 Promise<object>  这里会自动推断出返回的是 Promise<any>

你也可以这样定义函数类型:

/**
* @typedef {(method:MethodType,url:string,params:any)=>Promise<object>} RequesFn
*/
// 或
/**
* @typedef {{(method:MethodType,url:string,params:any):Promise<object>}} RequesFn
*/ // 使用:
/**
* @type {RequesFn}
*/
function myAjax(method, url, params) {
}

注意两种定义函数类型类型 RequestFn 的方式,和 ts 是完全一样的!

3、定义和使用泛型

/**
* @template T // 这里用 @template声明泛型类型T
* @typedef {{code:number,data:T,msg:string}} AxiosRes
*/ /**
* @typedef {{mediaId:string, mediaKey:string, token:string }} TokenRes
* @type {TokenRes|AxiosRes<TokenRes>} // 这里是泛型的使用
*/
let res

鼠标放到res变量上:

记住这个res,它是个复合类型的变量,下一节的类型强转就用它了

4、类型的强转(即ts中的类型断言)

if (/**@type {AxiosRes<TokenRes>} */(res).data === undefined) {
console.log('res 是TokenRes类型')
let mediaId = /**@type{TokenRes} */(res).mediaId
} else {
console.log('res 是AxiosRes<TokenRes>类型')
let mediaId = /**@type {AxiosRes<TokenRes>} */(res).data.mediaId
}

把注释去掉,其实很简单:

if (res.data === undefined) {
console.log('res 是TokenRes类型')
let mediaId = res.mediaId
} else {
console.log('res 是AxiosRes<TokenRes>类型')
let mediaId = res.data.mediaId
}

类型断言的方法就是 @type 注释后面将要断言的变量用括号括起来    /**@type{TokenRes} */(res)

更多示例,我就不列举了,可以查看官网:https://www.html.cn/doc/jsdoc/about-namepaths.html 自己学习了

加上jsDoc的好处

回到最开始的话题,你的公共项目如何给使用者完善的使用提示?

当你使用jsDoc时,你会发现 业务项目如果引用你的源码,会自然的带上提示

如果是引用你的dist压缩包,那么我们合理的组织代码,然后用   tsc --declaration --allowJs xxx.js  命令,生成 .d.ts 发布出去,一样会有良好的提示。

 

公共项目开发:我为什么用 JSDoc,而不用 ts的更多相关文章

  1. HTML+CSS项目开发总结

    好几天没更新博客了,刚实战完一个HTML+CSS的简单项目.经过几天的摸索,发现收益良多.之前只是单纯得写demo,看知识点,没有亲自实战项目.但实战过后才会了解,如何才能更好地提升自己的技术.针对这 ...

  2. 项目开发之使用 maven

    本文将详述 maven 在软件项目中的使用.首先讲述 maven 的基本工作原理及环境的搭建.然后讲述开发及配置管理人员如何使用 maven,最后将介绍 maven 与 eclipse 集成使用. m ...

  3. ASP.NET MVC 微信公共平台开发之获取用户消息并处理

    ASP.NET MVC 微信公共平台开发 获取用户消息并处理 获取用户消息 用户发送的消息是在微信服务器发送的一个HTTP POST请求中包含的,获取用户发送的消息要从POST请求的数据流中获取 微信 ...

  4. ASP.NET MVC 微信公共平台开发之验证消息的真实性

    ASP.NET MVC 微信公共平台开发 验证消息的真实性 在MVC Controller所在项目中添加过滤器,在过滤器中重写 public override void OnActionExecuti ...

  5. 使用Jquery+EasyUI 进行框架项目开发案例讲解之五 模块(菜单)管理源码分享

    http://www.cnblogs.com/huyong/p/3454012.html 使用Jquery+EasyUI 进行框架项目开发案例讲解之五  模块(菜单)管理源码分享    在上四篇文章 ...

  6. 使用Jquery+EasyUI 进行框架项目开发案例讲解之二---用户管理源码分享

    使用Jquery+EasyUI 进行框架项目开发案例讲解之二 用户管理源码分享   在上一篇文章<使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享>我们分享 ...

  7. 【推荐】使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享

    使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工管理源码分享   在开始讲解之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery的U ...

  8. 使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享

    使用Jquery+EasyUI 进行框架项目开发案例解说之中的一个 员工管理源代码分享 在開始解说之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery ...

  9. Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课

    Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课 本课程采用Q Q群直播方式进行直播,价值99元视频课程免费直播.完整的基于Swift项目实战,手把手教你做一个Swift版i ...

随机推荐

  1. NCoreCoder.Aop 国庆更新

    原本的IAopActors如下 public interface IAopActors { object Execute(AopContext context); Task<TResult> ...

  2. [COCOS2DX-LUA]0-006.cocos2dx中关于拖动屏幕物件,同时点击home键,返回后页面变黑的问题。

    基本信息介绍: 引擎框架: Quick-Cocos2dx-Community-3.6 测试机型: 魅族MX5 问题简介: 有拖动效果的物件,在拖动的工程中,手指不放,同时点击home键退到后台. 再返 ...

  3. Bytom DAPP 开发流程

    从目前已经发布的DAPP来看,DAPP架构大致可以分成3种类型:插件钱包模式.全节点钱包模式和兼容模式. 插件钱包模式是借助封装了钱包的浏览器插件通过RPC协议与区块链节点通信,插件在运行时会将Web ...

  4. Libsvm java工程实践

    在上篇文章中对libsvm的流程和简单的java代码测试做了说明,本篇简单对libsvm如何在工程中实践进行简短说明,不当的地方欢迎大家指正. 第一步是对libsvm的预测函数进行调整,我是从svm_ ...

  5. 微信小程序通过二维码获取参数运行

    小程序开发过程中会遇到参数id会通过二维码获取,然后执行接口获取数据,但是难免会遇到带过来的参数出现乱码,这样就需要解码,多个参数时就需要进行处理取我们需要的字段值:小程序开发过程中会遇到参数id会通 ...

  6. 使用JSPWiki丰富Unity-UPM包的使用

    1.简述 诸如npm.Nuget之类的包管理工具,Unity推出了自己的Unity Package Manager(UPM)工具来管理使用到的第三方库. 现在Unity Package Manager ...

  7. .NET Core 微服务—API网关(Ocelot) 教程 [四]

    前言: 上一篇 介绍了Ocelot网关和认证服务的结合使用,本篇继续介绍Ocelot相关请求聚合和Ocelot限流 一.请求聚合 Ocelot允许声明聚合路由,这样可以把多个正常的Routes打包并映 ...

  8. java 的API及Object类

    一 Java的API Java 的API(API: Application(应用) Programming(程序) Interface(接口)) Java API就是JDK中提供给我们使用的类,这些类 ...

  9. .NetCore(Avalonia) 项目dll混淆,Ubuntu 或者deepin操作系统 deb安装包解压,重新打包

    .NetCore(Avalonia) 项目dll混淆,deb安装包解压,重新打包 本文分为两部分,一部分是介绍使用 DotNetReactor6.0 及以上版本混淆.netcore项目的dll. 另一 ...

  10. .net Core使用sql语句实现批量修改数据状态

    上图为查出的所有满足条件的数据,要选中若干条数据将其状态设置为作废 一共选中6条数据,当点击确认后修改数据状态. 前端代码 1.安装NuGet包 [Abp.Dapper]于EFCore中, 2.创建文 ...