总结typescript常见报错信息

3,193 阅读3分钟

前言

  • 随着前端的不断强大,js这种弱类型需要被规范起来,就有了后面的ts强类型的崛起,来帮js将弱类型转为强类型,可以理解为java定义变量的形式,会持续更新关于ts的采坑之路...


两个方面

1. 在typescript中import第三方类库报错

  • 场景:我在做歌词的时候,因为要解析歌词,所以引入了lrc-file-parser库,结果采用常规的方法导入第一句话就提示错误,这是ts引起的报错信息:
  • TS7016: Could not find a declaration file for module 'lrc-file-parser'. 
    'D:/Work/wechat/node_modules/lrc-file-parser/vue-clipboard.js' implicitly has an 'any' type.   
    Try `npm install @types/lrc-file-parser` if it exists or add a new declaration (.d.ts) file containing 
    `declare module 'lrc-file-parser';

  • 错误原因
  • 因为第三方类库并没有ts的.d.ts 类型的声明文件,所以无法在目前的项目中正常使用。举个栗子,我们使用vant,首先是在项目里安装,然后再项目里引入。
  • npm i vant -S  //在项目里安装
    import { Toast } from 'vant'; //引入项目

  • 会发现这里并没有报错,我们查看node_modules,找到vant文件,发现里面有types文件夹,types文件夹里面有index.d.ts等文件,这个文件夹的用处就在于将弱类型转换为强类型,对插件里面的变量方法什么的进行了声明和定义。所以可以在typescript项目里正常使用。

  • 而我使用的lrc-file-parser库,在文件里都未发现types文件夹及index.d.ts等文件,所以项目不支持使用。

  • 查阅网上资料,可以自定定义(.d.ts)来描述库的类型和@types两种声明方式,第一次我模仿官网上jquery来写.d.ts(如下图:)不过没成功,就想着那就试试@types。


  • 解决方案

  • npm install @types/lrc-file-parser
  • 即lrc-file-parser安装的前提下再增加安装@types的npm modules即可,然后就尝试了一下,依旧报错(如下):
  • D:\Work\wechat>npm install @types/lrc-file-parser
    npm ERR! code E404
    npm ERR! 404 Not Found: @types/lrc-file-parser@latest
    npm ERR! A complete log of this run can be found in:
    npm ERR!     C:\Users\ever\AppData\Roaming\npm-cache\_logs\2019-06-17T03_21_01_988Z-debug.log

  • 这个原因是并没有vue-clipboard2的types声明文件,所以在使用之前还是需要在typesearch里面查看一下相关的类库是否有声明文件
  • microsoft.github.io/TypeSearch/ 查询结果如下:
  • 真的没有!!!
  • 如果你使用其他第三方插件,如clipboard,找得到就恭喜你,直接通过npm执行安装@types/clipboard插件(@types/第三方插件名)
  • 安装完成后就可以在项目中正常的使用clipboard了。

  • npm install --save @types/clipboard

  • 在项目中引入
  • import clipboard from 'clipboard';
    //注册到vue原型上(这里不是很明白,还没搞清楚)
    Vue.prototype.clipboard = clipboard;

  • 那么在@types也找不到相关的ts文件,应该怎么办
  • 在tsconfig.json编辑
  • "include": [
        "./typings-custom/**/*.ts"
    ]

  • 然后在项目的根目录新建文件夹typings-custom
  • 在里面新建一个文件ts,写什么呢
  • 按这个例子,我是使用解析歌词的lrc-file-parser库,那我就新建个lrc-file-parser.d.ts文件,内容如下:
  • declare module 'lrc-file-parser'

  • 重启,发现不会报错了,因为找到了该插件的ts文件了

2. Property 'validate' does not exist on type 'Vue | Element | Vue[] | Element[]'

  • 环境: vue2.5.2+element-ui2.2.2 +TypeScript
  • 位置: 在提交from 表单验证时
  • this.type = 'test'
    this.$refs['form'].validate(valid => {
         ... ...
    })

  • 错误信息:

  • 分析原因: Property ‘validate’ does not exist on type ‘Vue | Element | Vue[] | Element[]’ 意思是说validate找不到,它不知道是哪个类型的属性,因为我们这里用到了TypeScript,而TypeScript 又是强类型检查所以报了这个错。 

  • 解决方案:

  • this.type = 'test'
    (this.$refs['form'] as any).validate((valid : boolean)=> {
         ... ...
    })

  • 但是在接下来的运行中,又会报一个找不到表达式的错:

  • 解决方案: 因为在js中()可以代表一个函数的调用属性,所以当 this.type = “test” 没有加 ‘;'号时,js会默认后面的()是“test"方法的调用属性。

  • 如果不引入Form ,把Form 换成any 也是可以 的

  • import { Form } from "element-ui";
    
    this.type = 'test'; // 加分号!
    (this.$refs['form'] as Form).validate((valid : boolean)=> {
         ... ...
    })

  • 扩展知识:ts获取元素高度
  • (this.$refs.headerpoint as HTMLDivElement).clientHeight;
  • 关于ts内置对象的,不要一报错就使用any
  • 先看内置对象;
    用类型断言;
    泛型;
    不得已用any
  • ts内置对象文档(戳我)

参考

在typescript中import第三方类库clipboard报错:www.cnblogs.com/songForU/p/…

How to consume npm modules from typescript?:stackoverflow.com/questions/3…

Property 'validate' does not exist on type 'Vue | Element | Vue[] | Element[]':blog.csdn.net/qq_35257117…

文献

ts官方文档:ts.xcatliu.com/basics/decl…