ts在项目中的使用-三斜线引入 与 import区别

ts 在项目中的使用

本次分享内容只涉及项目初始阶段如何引入ts及依赖插件的ts。

ts为类型系统,js没有类型,为了在开发阶段减少错误而引入的系统。
ts有单独的配置文件,一般放在项目目录下
tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "experimentalDecorators":true,
    "baseUrl": "./",
    "paths": {
      "@/*":["src/*"]
    },
    "types": ["vite/client"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

ts与js运行时两套系统,虽然有时候代码是写在一起的,但他们运行时也是各自运行各自的代码。
比如 import {clone} from 'lodash',js系统引入的是clone函数,ts系统引入的是clone函数的类型。

1.ts 文件相关术语

  1. 模块文件: 含有 export 或者 import 的文件,文件名通常为: xx.ts
import lodash from 'lodash'
console.log(lodash)
  1. 声明文件: 不含实际运行代码 文件名通常为 xx.d.ts
    声明文件中
    声明文件也可以是模块文件,但其不含实际运行代码,所以导出的都是类型声明
type A = {name:string}
declare const a:A

2. 引入ts

npm install typescript -D
typescript安装后,其自带浏览器上使用的所有对象的定义文件,比如dom,标签等

const div:HTMLDivElement = document.createElement('div')

3.引入依赖

3.1. 引入模块文件

引入模块文件通常使用 import

import {A} from './a.ts'
const a:A ={name:'gg'}

3.2. 引入非模块类的声明文件

使用三斜线 reference 引入,有常用两种方式 pathtypes
他们区别就是 types 一般引入外部依赖的声明,path 一般引入自己写的声明
比如外部声明文件位置为node_modules/@types/b/index.d.ts,内容为type B={age:number},使用 path 和 types 引入方式如下:

/// <reference path="node_modules/@types/b/index.d.ts" />

/// <reference types="b" />

非模块的声明文件引入后为全局类型,可以直接使用
const b:B={age:100}
这儿可以看出,与js文件引入相比,ts多了一项寻址策略,它中会自动寻找node_modules/@types下的文件。

3. 声明合并 官网地址

“声明合并”是指编译器将针对同一个名字的多个独立声明合并为单一声明。 合并后的声明同时拥有原先多个声明的特性
常见的使用例子为扩展属性

点击查看代码
interface C  {
  a:string
  b:string
}

interface C {
  c:string
}
const v:C = {a:'',b:'',c:''}

4. vite+vue3 工程中的常见配置

所有依赖插件,在官网中有详细说明如何使用类型。

4.1 vite 注入的全局类型

vite注入了例如import.meta.env.BASE_URL,在import.meta中不存env属性,所以需要对ImportMeta类型进行补充,
其文件位置在node_modules/vite/client.d.ts。打开文件可以看到没有使用export 或者import。所以其为非模块声明,引入需要用到:

/// <reference types="vite/client" />

4.2 vue注入类型

vue类型文件在node_modules/vue/dist/vue.d.ts,打开后可以看到有export 和import关键字,所有必须使用import引入,
引入一次后可以在其它文件模块文件使用类型。
import 'vue'

4.2.1 注册全局组件

如果有注册全局组件,就需要对全局组件进行类型扩展。
如下扩展一个Layout组件

点击查看代码
import 'vue' // 此处说明此文件是模块文件
declare module 'vue' {
  export interface GlobalComponents {
   Layout: typeof import('./components/Layout.vue')['default']    
  }
}

4.2.2 注入.vue文件类型

当引入一个vue文件时,js编译器可以通过,但是ts却发现找不到。这是因为ts为.ts、.js、.tsx等文件已定义类型,vue文件需要手动定义类型

declare module '*.vue' {
	import { DefineComponent } from 'vue'
	// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
	const component: DefineComponent<{}, {}, any>
	export default component
}

4.2.3. 别名设置

在某些时候,路径使用别名会很方便,比如将@指向src
使用import data from '@/data'访问src/data.ts,由于ts与js是两套系统,虽然js能够正常运行,但ts并不知晓'@/data'路径指向哪儿,所以需要在tsconfig.json中也配置路径别名,需要配置compilerOptions.baseUrl与compilerOptions.paths

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*":["src/*"]
    },
  }
}

此处地址转换 @/data => ${baseUrl}src/data => ./src/data寻找到了正确地址。

4.3 编辑器配置

使用vscode + volar
volar能够自动按照tsconfig.json配置调用typescript做类型分析,不必将ts运行集成到项目中。也就是说类型系统由volar运行,js由项目本身运行。

5 vue3中api支持 官方文档

接口api工具 json2ts

将json转换成ts

遗留问题

在全局定义中 :declare let a:3
在其他文件中使用: let a = '' 不报错原因:declare let a 解释了一个全局的变量a 他的值是3,在模块文件中可以再次定义,就如fn内部能定义一个外部作用域的变量。当直接使用 a = '' 时出现报错

posted @ 2021-12-24 12:28  吃个石头  阅读(5879)  评论(0编辑  收藏  举报