TypeScript 07:工程化------import type、声明文件与 tsconfig
有 JS 基础即可阅读。建议先读第 01~06 课。
1. 类型和值分开搬运:import type
类型只活在编译期,所以「搬类型」有专用通道------运行时整句擦除:
ts
import type { User } from './types' // 只搬类型,运行时这行不存在
import { createUser, type User } from './user' // 值和类型混着搬,类型用内联 type
很多项目开启 verbatimModuleSyntax:带 type 修饰的导入完全丢弃,不带的原样保留 ------所以纯类型导入不写 type 会直接报错。
好处:意图明确(一眼看出搬的是类型);类型模块不会被错误打进产物;循环引用时更安全。
2. .d.ts:只有类型清单、没有实现的文件
声明文件 = 「编译器的通讯录」,三个来源:
- 社区维护 :
@types/lodash这类包(DefinitelyTyped 仓库) - 库自带:vue、pinia 把类型打进包里,不用额外装
- 自己写:库缺类型时的占位手段
自己写的两种典型形态:
ts
// shims.d.ts ------ 用 declare module 占位
declare module '*.vue' // 让编译器认识 .vue 后缀
declare module 'untyped-pkg' {
export function legacyTransform(input: string): string
}
ts
// 引用别人的声明集(三斜线指令)
/// <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 |