TypeScript工程化收益取决于编译期检查是否真正跑起来。严格模式、类型收窄、泛型约束和前后端类型共享四件事,能拦住大部分运行时才暴露的类型错误。本文给出可直接放进项目的配置和写法。
TypeScript工程化的起点:tsconfig严格配置
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "bundler",
"target": "ES2022",
"module": "ESNext"
}
}
strict开启全部严格检查;noUncheckedIndexedAccess让数组下标访问返回T|undefined,逼你把空值处理写出来;exactOptionalPropertyTypes对可选属性的类型更苛刻,跨模块传参时能提前暴露问题。
类型收窄:可辨识联合与守卫函数
type ApiResult =
| { ok: true; data: string }
| { ok: false; code: number; message: string };
function handleResult(r: ApiResult) {
if (r.ok) {
console.log(r.data.length);
} else {
console.error(r.code, r.message);
}
}
用ok这类判别字段做类型收窄,分支逻辑跟着类型走,比as any硬转可靠得多。遇到第三方库类型不完整,先看包类型声明,再写本地declare module补齐,不要为了省事用as any。
泛型约束:让函数类型跟着参数走
function pickField<T extends object, K extends keyof T>(
obj: T, key: K
): T[K] {
return obj[key];
}
K extends keyof T 把键约束在对象属性上,返回值类型T[K]随入参自动推导。泛型不是越抽象越好,能约束出具体属性的时候,读代码的人负担最小。
异步与网络层的类型安全
type Response<T> = { status: number; body: T };
async function getJson<T>(url: string): Promise<Response<T>> {
const res = await fetch(url);
return { status: res.status, body: (await res.json()) as T };
}
网络返回先用unknown接收,再通过校验函数收窄成具体类型,把解析逻辑保留在类型系统内。
前后端类型单源:接口规范驱动
接口用OpenAPI规范声明,前端用openapi-typescript生成类型,后端基于同一份规范提供实现。字段变更时编译期两边同时报错,联调成本明显下降。类型单源是工程化落地里收益最持久的一步。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/typescript-gong-cheng-hua-shi-zhan-yan-ge-mo-shi-yu-lei/