TypeScript 07:工程化——import type、声明文件与 tsconfig
有 JS 基础即可阅读。建议先读第 01~06 课。
1. 类型和值分开搬运:import type
类型只活在编译期,所以「搬类型」有专用通道——运行时整句擦除:
importtype{User}from'./types'// 只搬类型,运行时这行不存在import{createUser,typeUser}from'./user'// 值和类型混着搬,类型用内联 type很多项目开启verbatimModuleSyntax:带 type 修饰的导入完全丢弃,不带的原样保留——所以纯类型导入不写type会直接报错。
好处:意图明确(一眼看出搬的是类型);类型模块不会被错误打进产物;循环引用时更安全。
2. .d.ts:只有类型清单、没有实现的文件
声明文件 = 「编译器的通讯录」,三个来源:
- 社区维护:
@types/lodash这类包(DefinitelyTyped 仓库) - 库自带:vue、pinia 把类型打进包里,不用额外装
- 自己写:库缺类型时的占位手段
自己写的两种典型形态:
// shims.d.ts —— 用 declare module 占位declaremodule'*.vue'// 让编译器认识 .vue 后缀declaremodule'untyped-pkg'{exportfunctionlegacyTransform(input:string):string}// 引用别人的声明集(三斜线指令)/// <reference types="vite/client" />// 一行就能让 import.meta.env 拥有 Vite 环境变量的类型关键认知:声明文件让编译器「认识」一个东西,但不保证它运行时真的存在——编译通过 ≠ 运行有货。
3. tsconfig 的 strict 家族
strict: true是 7 个开关的打包,前三个最值得认识:
| 开关 | 管什么 | 你在哪见过它的报错 |
|---|---|---|
noImplicitAny | 不许「悄悄的 any」(参数不标、空数组乱装) | implicitly has an 'any' type |
strictNullChecks | null/undefined 必须显式处理 | Object is possibly 'undefined'(第 02 课) |
useUnknownInCatchVariables | catch 到的变量是 unknown | 'e' is of type 'unknown' |
其余四个(strictFunctionTypes/strictBindCallApply/strictPropertyInitialization/noImplicitThis)日常较少单独遇到,保持开启即可。
项目常见的安全加分项:noUncheckedIndexedAccess(第 05 课的读取带 undefined)、noUnusedLocals/noUnusedParameters(写了不用的变量会报错)、verbatimModuleSyntax。
收紧策略:新项目直接全开;老项目按noImplicitAny→strictNullChecks→ 全套 strict 的顺序逐步收紧,别一次全开把报错刷成瀑布。
4. 高频报错速查
| 报错 | 人话 |
|---|---|
Could not find a declaration file for module 'x' | 库没类型:装@types/x或自己 d.ts 占位 |
Parameter 'x' implicitly has an 'any' type | noImplicitAny 拦住了瞎猜 |
'e' is of type 'unknown' | catch 变量先收窄再使用 |
... must be imported using a type-only import | verbatimModuleSyntax:纯类型导入要写type |