1. 声明文件
- 主要作用:
- 类型声明:为库或模块提供类型信息。
- 全局声明:为全局作用域中的类型和变量提供声明。
- 类型兼容性:确保第三方库或自定义代码的类型正确性。
- 代码提示与检查:在开发环境中提供更好的代码提示和类型检查。
通过使用 .d.ts 文件,可以显著提高 TypeScript 项目的类型安全性和开发体验。
.d.ts文件
称为
类型声明
或类型定义
文件- .d.ts文件的来源
- 内置。例如:typescript包中自带的ES6的声明文件
- 第三方库。通过npm安装的包里面
- 自定义。自己写的.d.ts文件
- .d.ts文件的来源
- 第三方库的声明文件
- 库中本身包含声明文件,例如:
axios
通过import axios from "axios";
就可以引入 - 如果第三方库中没有包含声明文件,可以去
yarn官网
查找,推荐使用yarn包管理工具
- 自定义第三方库的声明文件
- 库中本身包含声明文件,例如:
2. 自定义声明文件
- 声明文件的文件后缀:
.d.ts
- 关键字
declare
用于声明全局变量、类型、函数、类或模块,告诉TypeScript编译器这些声明已经存在于运行时环境中。
declare
与type和interface
的区别:
type和interface
重点在于结构,某一个变量、函数、类的结构;declare
重点在于告诉整个项目,某一个变量、类、模块存在,让ts可以识别,同时说明它们是什么类型,有什么方法、属性可以使用
1. 声明常量、变量、函数、类
- 在什么情况下需要声明
- 假设
main.ts
想要使用index.js
文件中的数据,通常我们使用import
来导入index.js
文件便于使用index.js
文件中的数据。 - 那么现在就不使用
import
,假设在一个html文件
的<script>
中引入了index.js
和main.ts
两个文件,虽然这两个文件都被引入了同一个html
文件中,但是main.ts
并不知道index.js
有什么类型的数据,根本无法使用,这时候需要.d.ts
文件来声明index.js
文件中的数据,声明后main.ts
文件中就可以使用了 - 总结:已经知道有一个可以使用的数据(数据的结构可以是常量、变量。。。),多个ts文件想要使用,或者说没有必要引入,就可以使用声明的方式来使用
- 假设
- 声明文件
// 声明变量
declare let userName: string;
// 声明常量
declare const OK: boolean
// 声明函数
declare function getInfo(id: number): string;
// 声明类
declare class User {
constructor(public id: number, public name: string);
}
- index.js文件中的内容
const OK = true // 常量
let userName = 'zhangsan' // 变量
function getInfo(id){ // 函数
return 'lisi'
}
function User(id, name){ // 类
this.id = id
this.name = name
}
- main.ts文件
// 使用变量
console.log(userName)
// 使用常量
console.log(OK)
// 使用函数
console.log(getInfo(1))
// 类
const user = new User(1, 'zhangsan')
console.log(user)
- 结果
zhangsan
true
lisi
User {id: 1, name: 'zhangsan'}
2. 声明资源类文件
示例:导入图片
- 声明文件
// 声明文件模块
declare module "*.png"
declare module "*.jpg"
declare module "*.jpeg"
declare module "*.gif"
- mani.ts
import meiNv from './assets/111.jpg' // 如果没有声明.jpg文件,这里报错
const dom = document.createElement('img')
dom.src = meiNv
document.body.appendChild(dom)
// 导入图片需要在webpackconfig.js中配置打包规则
module: {
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
]
}
3. 声明模块
- 用法略有不同,声明的模块需要使用
import
导入
// 声明模块,重点在于模块中所导出的东西,说明在这个模块中有些什么东西可以使用
declare module "myModule" {
export function foo(): void; // 模块中的函数
export const bar: number; // 模块中的常量
export class Foo {} // 模块中的类
}
- main.js
import myModule from "myModule"; // 引入模块
myModule.foo(); // 使用模块中的数据
myModule.bar = 20
new myModule.Foo()
4. 声明文件
- 使用
import App from './App.vue'
时会报.vue
类型错误,因为ts
不认识.vue文件,所以声明.vue
文件是DefineComponent
类型,这样就不会报错了
// 声明'.vue'文件
declare module ".vue" {
import { DefineComponent } from 'vue'
const component: DefineComponent
export default component
}
3. tsconfig.json
1. 作用
- 让tsc编译代码的时候,知道如何去编译ts文件同时做类型检测
- 比如是否允许不明确的this选项,是否允许含有隐式的any类型
- 编译后的js代码是什么版本?ES3、ES5?
- 编辑器同时也在读取该文件,用于代码检测,提示错误
- 有该文件的目录,会被识别为ts项目的根目录
2. 在编译时如何被使用
- 在命令行输入
tsc
命令,会在目录中寻找tsconfig.json
文件,读取到配置后,会将该目录下的所有ts
文件按照config
中的配置编译为js
文件- 如果
tsc
后面加了参数或者文件名,则tsc
不会读取config
文件
- 如果
webpack
使用ts-loader
进行打包时,读取config
文件,根据config
中的配置来编译ts
文件
3. tsconfig中的配置项
官网介绍链接
"module": "commonjs" // 最终生成的代码使用的模块化
"esModuleInterop": true, // es module 和 commonjs可以互相调用,有些库使用commonjs,而我们的项目使用es module,在项目中可以使用import导入commonjs
"strict": true, // 严格的类型检测
"skipLibCheck": true // 是否跳过.d.ts文件中的类型检测
"allowJs": true, // 是否允许在ts文件中使用js代码
"jsx": "preserve", // jsx的处理方式(preserve:保留原有的jsx格式)
"importHelpers": true, // 是否导入一些需要的功能模块
"moduleResolution": "node10", // 在import ··· from 'XXX' 时,指定查找XXX的规则
"allowSyntheticDefaultImports": true
/* 导出时:export {aa, bb, cc}
导入时:import * as x from 'index.js' 使用时:x.aa x.bb
如果配置为 true
可以使用:import x from 'index.js' 写法
*/
"sourceMap": true, // 是否生成映射文件
// 作用:在ts文件与编译好的js文件之间做映射,可以方便的查找报错后对应的ts代码的位置
"baseUrl": ".", // 设置基本路径,基本路径设置为当前项目的根目录,如不设置,默认指定的也是根路径
"paths": {
"@/*": ["src/*"] // 设置路径别名,"src/*"是从根路径开始,根路径是baseUrl指定的
}
搭建webpack环境
在html页面中运行javascript
- node项目初始化
pnpm init -y
- 安装webpack及相关插件
pnpm add webpack webpack-cli webpack-dev-server -D
- 安装ts-load,并初始化ts配置文件
// 初始化ts环境,无法执行,需要全局安装typescript
tsc --init
// 全局安装typescript
pnpm install tapyescript -g
// 安装ts-load,webpack中
- 安装html-webpack-plugin
pnpm add html-webpack-plugin -D
- package.json
{
"name": "ts-webpack",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"dev": "webpack server --mode development --open --hot"
},
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"html-webpack-plugin": "^5.6.0",
"ts-loader": "^9.5.1",
"webpack": "^5.95.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.1.0"
}
}
- webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const config = {
mode: "development",
entry: "./src/index.ts",//入口文件
output: {// build时,打包目录
filename: "bundle.js",
path: path.resolve(__dirname, "./dist"),
},
resolve: { // import 这些文件时,可以省略后缀
extensions: [".json", ".ts", ".js","cjs"],名
},
module: {
rules: [
// 以.ts结尾的文件,指定使用ts-loader加载器来处理
{
test: /\.ts$/,
loader: "ts-loader",
},
],
},
plugins: [
new HtmlWebpackPlugin({ //把入口文件编译成js后注入到指定的模板文件的,指定位置,这里指定的是body
template: "./index.html", // 指定模板文件
filename: "index.html", // 输出文件名
inject: "body", // 注入的位置,
}),
],
};
module.exports = config;
- 目录结构