TypeScript
官方文档:
1,index.d.ts
index.d.ts是 TypeScript 中的一种命名约定,它有特定的用途和意义:
index 部分 :在 Node.js 和许多前端构建工具中, index 文件是一个模块的默认入口点。当你导入一个目录而不是具体文件时(例如 import * from './directory' ),系统会自动查找该目录下的 index 文件。
.d.ts 后缀 : .d.ts 是 TypeScript 的类型声明文件扩展名。这些文件只包含类型信息,不包含实际的 JavaScript 代码实现。它们的作用是:
为 JavaScript 库提供类型定义
允许 TypeScript 编译器理解库的 API
提供代码补全和类型检查功能
在你看到的 VitePress 的 index.d.ts 文件中,它包含了 VitePress 的所有公共 API 的类型定义。这个文件让使用 TypeScript 的开发者能够获得 VitePress API 的类型提示和类型检查。
当其他开发者在他们的项目中使用 VitePress 时,TypeScript 编译器会读取这个声明文件来了解 VitePress 的 API 结构,从而提供更好的开发体验。
2, JavaScript和TypeScript区别
适用场景:
JavaScript 适用场景
小型项目或原型开发
- 快速启动,无需配置类型系统
- 开发周期短,需要快速迭代
- 快速启动,无需配置类型系统
脚本类任务
- 简单的自动化脚本
- 一次性的工具脚本
- 简单的自动化脚本
团队对 TypeScript 不熟悉
- 学习成本考虑
- 团队习惯于 JavaScript 开发
- 学习成本考虑
与特定框架集成较好
- 某些旧框架可能对 TypeScript 支持不完善
浏览器直接运行的代码
- 无需构建步骤的简单网页
TypeScript 适用场景
中大型项目
- 代码量大,需要更好的组织和维护
- 多人协作开发
- 代码量大,需要更好的组织和维护
长期维护的项目
- 需要良好的代码文档和类型提示
- 频繁重构和功能迭代
- 需要良好的代码文档和类型提示
库和框架开发
- 提供良好的类型定义给使用者
- 增强 API 的可发现性和使用体验
- 提供良好的类型定义给使用者
复杂业务逻辑
- 类型系统帮助捕获潜在错误
- 减少运行时错误
- 类型系统帮助捕获潜在错误
团队协作
- 明确的接口定义
- 代码自文档化
- 明确的接口定义
在 weapp-vite 这样的工具库项目中,使用 TypeScript 是很好的选择,因为它需要提供稳定的 API、支持长期维护,并且需要良好的开发体验。
- 类型系统:
// JavaScript
let name = "张三";
name = 123; // 可以随意改变类型
// TypeScript
let name: string = "张三";
name = 123; // 错误:不能将类型"number"分配给类型"string"- 接口定义:
// TypeScript 支持接口
interface Article {
title: string;
date: string;
tags: string[];
}
// 使用接口约束对象结构
const article: Article = {
title: "文章标题",
date: "2024-01-01",
tags: ["JavaScript", "TypeScript"]
};- 类型注解:
// TypeScript 支持类型注解
function calculateTotal(price: number, quantity: number): number {
return price * quantity;
}
// JavaScript 没有类型注解
function calculateTotal(price, quantity) {
return price * quantity;
}- 编译时检查:
- TypeScript 在编译时进行类型检查
- JavaScript 在运行时才能发现类型错误
- 开发工具支持:
- TypeScript 提供更好的代码提示和重构功能
- JavaScript 的 IDE 支持相对较弱
- 学习曲线:
- JavaScript 入门更简单
- TypeScript 需要学习额外的类型系统概念 在你的项目中使用了 TypeScript,这有助于:
- 提前发现潜在错误
- 提供更好的代码提示
- 提高代码可维护性
- 更容易进行大型项目开发
commonjs和TypeScript写法
commonjs:
export const themeConfig: DefaultTheme.Config = {
nav,
sidebar,
// ... 其他配置
}TypeScript:
export const themeConfig = {
nav,
sidebar,
// ... 其他配置
} as DefaultTheme.Config;as是 TypeScript 的类型断言,它的作用是:
类型检查:告诉 TypeScript 编译器这个配置对象符合 VitePress 的 DefaultTheme.Config 接口定义
类型提示:在编辑器中可以获得正确的代码提示和类型检查
类型安全:确保配置对象包含了必要的属性,并且属性值类型正确
两种方式都可以,效果是一样的。第一种是显式类型声明,第二种是类型断言,都能确保类型安全。
3,tsconfig.json 的作用
tsconfig.json 是 TypeScript 项目的配置文件,它起到以下几个关键作用:
主要功能
定义编译选项 :指定 TypeScript 编译器如何将 TypeScript 代码转换为 JavaScript 代码
目标 JavaScript 版本 (target)
模块系统 (module)
严格类型检查选项 (strict)
输出目录 (outDir)
-moduleResolution 配置项决定了 TypeScript 如何查找和解析模块
## "moduleResolution": "node"
这种模式模仿 Node.js 的模块解析机制:
- 对于相对导入路径(以 ./ 或 ../ 开头),会在相对目录中查找
- 对于非相对导入路径,会从当前目录的 node_modules 开始查找,然后逐级向上查找父目录的 node_modules
- 支持 package.json 中的 main 字段
- 适合 Node.js 环境或使用 CommonJS 模块的项目
## "moduleResolution": "Bundler"
这是较新的模式,为现代打包工具(如 Webpack、Vite、esbuild 等)设计:
- 结合了 Node.js 和 ECMAScript 模块解析的特点
- 支持 package.json 中的 exports 字段(包导出映射)
- 更好地支持 ESM 模块规范
- 适合使用现代打包工具的前端项目指定项目范围 :通过 include 和 exclude 字段确定哪些文件应该被编译
配置类型检查 :设置类型检查的严格程度和特性
路径映射 :通过 paths 配置模块导入路径别名
// 使用别名导入
import { something } from '@/utils/helpers';
// 不使用别名则需要这样(可能会有很长的相对路径)
import { something } from '../../utils/helpers';tsconfig.json基础配置
{
// 继承根包
"extends": "../../tsconfig.json",
"compilerOptions": {
// 指定生成的JavaScript的版本,ESNext表示使用最新的ECMAScript特性
"target": "ESNext",
// 指定生成的模块系统,ESNext表示使用最新的ECMAScript模块系统
"module": "ESNext",
// 指定模块解析策略,Bundler适用于使用打包工具的项目
"moduleResolution": "Bundler",
// 允许导入JSON文件作为模块
"resolveJsonModule": true,
// 指定额外的类型声明文件
"types": [
"vitest/globals"
],
// 允许编译JavaScript文件
"allowJs": true,
// 启用所有严格类型检查选项
"strict": true,
// 允许导入没有默认导出的模块时使用默认导入语法
"allowSyntheticDefaultImports": true,
// 启用CommonJS和ES模块之间的互操作性
"esModuleInterop": true,
// 跳过对声明文件的类型检查,提高编译速度
"skipLibCheck": true,
// 生成声明文件(.d.ts)
"declaration": true,
// 确保文件名大小写一致性
"forceConsistentCasingInFileNames": true,
// 启用源映射,便于调试
"sourceMap": true,
// 删除所有注释,减小输出文件体积
"removeComments": false,
// 指定输出目录
"outDir": "./dist"
},
// 指定要包含在编译中的文件或目录
"include": [
"src/**/*"
],
// 指定要排除在编译之外的文件或目录
"exclude": [
"node_modules",
"dist"
]
}4,项目构建工具
这个项目使用了多种构建工具的组合,主要包括:
Turborepo (turbo) :作为 monorepo 的任务编排工具,负责协调各个包的构建、测试等任务。从根目录的 package.json 中可以看到大量使用了 turbo run 命令。
tsup :作为实际的 TypeScript 构建工具,用于将 TypeScript 代码编译为 JavaScript。这是一个基于 esbuild 的高性能构建工具,适合库的打包。
unbuild :某些包可能使用了 unbuild 作为构建工具,它提供了更多的配置选项。
项目的构建流程大致是:
Turborepo 负责调度和并行执行各个包的构建任务
各个包内部使用 tsup 或 unbuild 进行实际的代码编译和打包
TypeScript 编译器 (tsc) 主要用于类型检查,而不是实际的代码生成
从 tsconfig.json 的配置来看,项目使用了现代的 ESM 模块系统和打包工具,这与 tsup 的定位相符。
5,解构赋值 类型注解
解构赋值 是 JavaScript 的语言特性,ECMAScript 6 (ES6) 引入的,所有现代 JavaScript 环境都支持,包括 Node.js。类型注解 是 TypeScript 特有的,用于静态类型检查
这种类型注解方式是 TypeScript 特有的,在编译后会被移除,不会影响运行时的 JavaScript 代码。
typescript高级写法:
TypeScript 中的一种高级参数模式
async buildPackage(
{ dep, outDir, options, isDependenciesCacheOutdate, heading = '', subPackage }:
{ dep: string, outDir: string, options?: TsupOptions, isDependenciesCacheOutdate: boolean, heading: string, subPackage?: SubPackage },
) {它有以下优点:
参数顺序不重要,调用时通过属性名指定
可以轻松添加或移除参数而不破坏现有代码
函数调用时参数的用途更加清晰
类型安全,编译器会检查参数类型
