增强VSCode智能感知能力

前言

本文说的类型支持仅仅是 VS Code 的 IntelliSense 功能,并非静态类型语言的类型检查,所以对开发的效率提升不大,但是可以提高项目的可维护性,即所谓代码即文档 CaaD(Code as a Documentation)。

一、VS Code 的 IntelliSense 功能

使用过 IDE 与静态类型语言的同学可能很熟悉了,比如 VS/C# 的自动导入命名空间、Code Refactor(重命名属性/方法/类名等标识符,并自动修改所有的引用)、转到定义(转到声明、查找引用)甚至代码段提取(提取一段代码作为一个函数,并自动将依赖的变量作为参数输入)等各种强大的功能。

而 JS 是一个动态类型的语言,为了支持上述功能,VS Code 团队开发了一个插件,名为 Visual Studio IntelliCode,最早该插件是作为一个外部扩展,后来直接作为内部扩展,可以直接使用。

以下摘自官网描述:

IntelliSense is a general term for a variety of code editing features including: code completion, parameter info, quick info, and member lists. IntelliSense features are sometimes called by other names such as "code completion", "content assist", and "code hinting."

翻译过来就是:

IntelliSense是各种代码编辑功能的通用术语,包括:代码完成、参数信息、快速信息和成员列表。IntelliSense功能有时被称为其他名称,如“代码完成”、“内容辅助”和“代码提示”。 

特别注意:在成员提示被关闭的情况下可以使用快捷键 Ctrl+Space 重新打开成员提示(极大的可能与 Windows 系统默认的输入法切换键冲突导致失效,此时可以考虑更换快捷键),与 Ctrl+Shift+Space 打开参数提示。

二、配置 jsconfig.json

首先要说的是用 vue 脚手架生成的项目中,并无该文件,且一般情况下没有该文件也会有 IntelliSense 功能。

这里配置 jsconfig.json 的必要原因是:

无该文件会导致项目内的 .d.ts 文件不一定被加载;

对于 Vue 项目来说,导入时使用 @ 是很常见的行为,但是这将会导致 IntelliSense 无法识别。

一个常见的 jsconfig.json 配置如下:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "include": [
    "./src/**/*.d.ts",
    "./src/**/*.js",
    "./src/**/*.vue"
  ]
}

这个 jsconfig.json 包含了对导入时 @ 的解析以及扫描项目 src 目录及其子目录下的 .d.ts、.js、.vue 文件,以建立类型、引用等相关信息(转到定义、查找引用以及自动导入的关键)。

配置完成后重新加载(Ctrl+Shift+P 输入 Reload Window 并回车)即可。此时输入 import '@/' 后会有路径提示(如果没有可能是还没有加载完成,耐心等待一会儿)。

值得注意的是,导入 SFC 文件时,文件的路径必须添加 .vue 后缀:

import Display from '@/components/display/display.vue'

 这样的话你就可以将光标移动到组件名称上按下 F12 键以导航到组件的定义,否则是无法导航到组件定义的。

另外,配置完成后,还可以在 <template> 标签中得到自定义组件的补全提示,如果没有导入,甚至可以在敲回车补全时自动导入:

三、JSDoc 注释

即使用注释来说明代码。在 VS Code 中可以通过在 js 类型的文件中输入 /** 来触发 JSDoc 代码片段,以下是一些实例:

/**
 * 注释1
 */
const info = 'info'

/**
 * 注释2。
 */
const person = {
  /** 姓名 */
  name: 'hello',
  /** 年龄 */
  age: 2
}

/**
 * 将一个字符串反过来。
 * @param {string} str 需要反转的字符串。
 * @returns {string} 反转后的字符串。
 */
function reverseString (str) {
  return str.split('').reverse().join('')
}

这种注释可以提供如下的效果,在成员提示的列表中可以显示注释内容,即做到文档的效果(同时鼠标悬浮时也会有文档的提示):

 

 

 可以看到,第二张图标注了传入参数 str 的类型,在输入 str.sp 时会给予成员提示,敲回车键后即会自动完成。

四、类型声明文件

类型声明文件是一个 .d.ts 文件,使用过 TypeScript 的同学应该不陌生,在使用 TypeScript 开发库项目时,如果需要发布到 npm 仓库,则需要编译成 js 发布,并可以用 tsc 生成对应的类型声明文件,以供使用者参照。

对于没有 TypeScript 的 Vue 项目,仍然可以使用 .d.ts 文件带来的部分便利,虽然需要手写 .d.ts 文件。

一个 .d.ts 文件的例子如下:

/**
 * 应用数据的模型。
 */
declare type Model = {
  /**
   * 应用数据的属性字典。
   */
  dataMap: {
    [key in PropertyNames]: Property
  }

  /**
   * 属性名称列表。
   */
  PropertyList: string[]
}

/**
 * 应用数据的数据属性名称列表。
 */
declare type PropertyNames ='id' | 'type' | 'key' | 'summary'

/**
 * 应用数据的属性定义。
 */
declare interface Property {
  /**
   * 属性的名称。
   */
  name: string

  /**
   * 属性值的可读形式。
   */
  label: string

  /**
   * 属性值。
   */
  value: PropertyValue
}

/**
 * 属性值的类型。
 */
declare type PropertyValue = boolean | number | string | boolean[] | number[] | string[]

上述代码并不会生成 js 代码,仅仅在开发期间被编辑器或集成开发环境识别以用作代码自动完成、成员提示等功能。在数据结构较为复杂时,可以利用类型声明文件作为文档以提高项目的可维护性。

虽然类型声明文件不参与 js 代码的执行,但是仍然可以利用类型声明文件影响到 js 代码的编写,将上述类型声明文件保存后,即可在 js 代码中以 JSDoc 的形式引用:

/**
 * 应用数据模型。
 * @type {Model}
 */
const model = {
  dataMap: {
    id: 1
  }
}

console.log(model.dataMap.id.value)

 效果如下:

 

 

deprecated

简单来讲就是,若某类或某方法加上该注解之后,表示此方法或类不再建议使用,调用时也会出现删除线,但并不代表不能用,只是说,不推荐使用,因为还有更好的方法可以调用。

/**
 * @deprecated 请使用 xxx 替代。
 */
const preson = {}

export { preson }

 

五、SFC 的成员类型

<template>
  <div>
    <input v-model="value" />
  </div>
</template>

<script>
export default {
  props: {
    /**
     * 应用数据模型。
     * @type {import('vue').PropOptions<Model>}
     */
    model: {
      type: Object,
      required: true
    },
    /**
     * 需要编辑的字段。
     * @type {import('vue').PropOptions<PropertyNames>}
     */
    property: {
      type: String,
      required: true
    }
  },
  data () {
    return {
      value: this.model.dataMap[this.property].value,
      /**
       * @type {Model}
       */
      other: {}
    }
  },
  methods: {
    /**
     * 获取属性值。
     * @param {Model} issue 应用数据模型。
     * @param {PropertyNames} property 属性名称。
     * @returns {PropertyValue} 属性值。
     */
    getPropertyValue (issue, property) {
      issue.dataMap[property].value
    }
  }
}
</script>

上面分别标记了 props、data、methods 的数据类型、参数及返回值,在引用这些属性、变量时,将会有自动完成提示、参数信息等:

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值