
TypeScript 数据类型全解析与转换指南
一、核心数据类型体系
1. 基础类型(Primitive Types)
| 类型 | 描述 | 示例 | 特殊说明 |
|---|---|---|---|
number |
数值类型(含整数、浮点数、科学计数法) | let age: number = 25; |
支持二进制(0b)、八进制(0o)、十六进制(0x)字面量 |
string |
字符串类型 | const str: string = "TypeScript"; |
支持模板字符串(Hello ${name}) |
boolean |
布尔值 | let flag: boolean = true; |
仅 true/false 两个值 |
symbol |
唯一标识符 | const sym: symbol = Symbol(); |
用于对象属性的唯一键 |
bigint |
任意精度整数 | const big: bigint = 123n; |
需添加 ESNext 到 tsconfig.lib |
2. 复合类型(Compound Types)
| 类型 | 描述 | 示例 |
|---|---|---|
Array<T> / T[] |
数组类型 | const arr: number[] = ; |
Tuple |
固定长度和类型的数组 | let tuple: @ref; |
enum |
枚举类型(数字/字符串枚举) | enum Color { Red, Green } |
object |
非原始类型(排除 number/string/boolean 等) |
const obj: object = { a: 1 }; |
any |
任意类型(慎用) | let data: any = apiResponse; |
unknown |
安全的未知类型(需类型守卫) | let input: unknown = getInput(); |
3. 特殊类型
| 类型 | 描述 | 示例 |
|---|---|---|
void |
无返回值函数 | function log(): void {} |
never |
永不存在值的类型(抛出异常/死循环) | function error(): never {} |
literal |
字面量类型(精确匹配特定值) | `type Status = "success" |
二、类型转换全攻略
1. 显式类型转换
1.1 类型断言(Type Assertion)
typescript
// 尖括号语法
const str: unknown = "123";
const num: number = (<string>str).length;
// as 语法(推荐)
const arr: any@ref;
const filtered = arr.filter((item): item is number => typeof item === "number");
1.2 函数转换
typescript
// 字符串转数字
const numStr: string = "123.45";
const num: number = Number(numStr); // 123.45
const int: number = parseInt(numStr, 10); // 123
// 数字转字符串
const num: number = 42;
const str1: string = String(num); // "42"
const str2: string = num.toString(); // "42"
2. 隐式类型转换
2.1 运算符驱动
typescript
// 字符串拼接
const result = 5 + "px"; // "5px"(数字隐式转字符串)
// 逻辑运算
const isAdmin = true;
const isAdminStr = isAdmin + ""; // "true"(布尔值转字符串)
// 算术运算
const value = "10" - 5; // 5(字符串转数字)
const isTruthy = !!value; // true(数字转布尔)
2.2 类型收窄(Type Narrowing)
typescript
function printLength(value: unknown) {
if (typeof value === "string") {
console.log(value.length); // 类型收窄为 string
} else if (Array.isArray(value)) {
console.log(value.length); // 类型收窄为 any[]
}
}
三、避坑指南与最佳实践
1. 类型转换常见陷阱
| 问题类型 | 示例 | 修复方案 |
|---|---|---|
| 隐式转换导致的精度丢失 | const a: number = 0.1 + 0.2; |
使用 toFixed() 控制精度 |
| any 类型滥用 | let data: any = apiResponse; |
改用泛型 + 类型守卫 |
| null/undefined 处理 | const len = str.length; |
添加非空断言 str!.length 或默认值 |
| 枚举反向映射失效 | enum Color { Red = 1 } |
使用 Color 时需确保唯一性 |
2. 安全转换模式
typescript
// 安全解析 JSON
const parseJSON = <T>(json: string): T => {
try {
return JSON.parse(json);
} catch {
throw new Error("Invalid JSON");
}
};
// 类型守卫组合
const isUser = (obj: unknown): obj is User => {
return (
typeof obj === "object" &&
"id" in obj &&
typeof (obj as User).id === "string"
);
};
3. 性能优化技巧
typescript
// 避免重复类型断言
const process = (data: unknown) => {
const str = data as string; // 单次断言
return str.toUpperCase();
};
// 使用类型谓词减少重复检查
type Primitive = string | number | boolean;
const isPrimitive = (val: unknown): val is Primitive => {
return val === null || typeof val !== "object";
};
四、进阶类型转换
1. 高级类型操作
typescript
// 映射类型转换
type ReadonlyUser = Readonly<User>;
// 条件类型过滤
type FilterString<T> = T extends string ? T : never;
// 模板字面量类型
type Event = "click" | "hover";
type Handler = `${Event}Handler`;
2. 运行时类型校验
typescript
// Zod 校验库示例
import { z } from "zod";
const UserSchema = z.object({
id: z.string().uuid(),
age: z.number().int().positive(),
});
const parseUser = (input: unknown) => {
return UserSchema.parse(input);
};
五、实战建议
-
类型优先原则 :优先使用
unknown而非any,通过类型守卫逐步缩小范围 -
严格模式配置 :
json// tsconfig.json { "compilerOptions": { "strictNullChecks": true, "noImplicitAny": true, "strictFunctionTypes": true } } -
类型文档化 :为复杂类型添加 JSDoc 注释
typescript/** * @typedef {Object} User * @property {string} id - 用户唯一标识 * @property {"admin"|"user"} role - 用户角色 */
通过掌握类型系统的核心机制和转换技巧,开发者可以显著提升代码健壮性。建议结合具体业务场景,灵活运用类型断言、类型守卫和高级类型工具,构建类型安全的代码体系。

React/Vue/Angular项目中,类型转换有哪些特殊注意点
在 React/Vue/Angular 项目中使用 TypeScript 时,类型转换需特别注意框架特性与类型系统的交互。以下是各框架的核心注意事项及通用最佳实践:
一、React 项目注意事项
1. 组件 Props 类型安全
-
问题 :直接传递
any类型或未定义 Props 会导致运行时错误 -
解决方案 :
tsx// 使用泛型精确约束 interface User { id: string; name: string } const UserProfile = ({ user }: { user: User }) => { /* ... */ } // 使用 TypeScript 的泛型约束 const fetchUser = <T extends { id: string }>(id: T["id"]): Promise<T> => { /* ... */ }
2. 事件处理类型
-
问题:未正确标注事件对象类型会导致属性访问错误
-
解决方案 :
tsxconst handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { e.preventDefault(); // 自动提示 preventDefault 方法 }
3. 状态管理类型
-
问题:useReducer/useContext 的泛型缺失导致类型推断错误
-
解决方案 :
tsxtype State = { count: number }; const [state, dispatch] = useReducer(reducer, initialState as State);
二、Vue 项目注意事项
1. 响应式类型推导
-
问题:reactive/ref 的初始值类型推断不准确
-
解决方案 :
ts// 显式标注类型 const count = ref<number>(0); const user = reactive<{ name: string }>({ name: "John" });
2. 组件 Props 与 Emits
-
问题:未使用 defineProps/defineEmits 导致类型丢失
-
解决方案 :
ts// script setup 语法 const props = defineProps<{ list: Array<{ id: number }>; }>(); const emit = defineEmits<{ (e: "update", value: string): void; }>();
3. 解构响应式对象
-
问题:解构导致响应性丢失
-
解决方案 :
ts// 正确方式 const { foo } = toRefs(state); // 错误方式(失去响应性) const { foo } = state;
三、Angular 项目注意事项
1. 依赖注入类型
-
问题:未标注服务类型导致注入错误
-
解决方案 :
ts@Injectable({ providedIn: 'root' }) class DataService { getData(): Observable<Data[]> { return of([] as Data[]); } }
2. RxJS 类型操作
-
问题:未正确标注 Observable 类型
-
解决方案 :
tsgetData(): Observable<{ id: string }[]> { return this.http.get<{ id: string }[]>('/api/data'); }
3. 模板类型检查
-
问题:模板中访问未定义的属性
-
解决方案 :
html<!-- 使用安全导航操作符 --> <div *ngIf="user?.address?.city"></div>
四、跨框架通用最佳实践
1. 类型断言陷阱
-
问题 :滥用
as导致运行时错误tsx// 错误示例 const data = localStorage.getItem("key") as string; // 可能为 null -
解决方案 :
tsconst data = localStorage.getItem("key"); if (typeof data === "string") { // 安全操作 }
2. 第三方库类型处理
-
问题:缺乏类型定义导致类型错误
-
解决方案 :
ts// 声明文件补充 declare module "legacy-lib" { export function getData(): Promise<{ id: string }[]>; }
3. 异步数据类型
-
问题:未处理 Promise 的泛型类型
-
解决方案 :
tsconst fetchData = async (): Promise<User[]> => { const res = await fetch("/api/users"); return res.json() as Promise<User[]>; // 需要运行时验证 }
4. 类型守卫实践
-
问题:未正确缩小联合类型范围
-
解决方案 :
tsfunction isUser(obj: unknown): obj is User { return "id" in obj && typeof obj.id === "string"; }
五、框架对比与特殊场景
| 场景 | React | Vue | Angular |
|---|---|---|---|
| DOM 操作类型 | 使用 ref + 类型断言 |
使用 ref 显式标注 |
使用 @ViewChild 类型参数 |
| 状态管理 | Redux Toolkit 的 createSlice 泛型 |
Pinia 的 defineStore 类型推导 |
NgRx 的 Action 类型标注 |
| 表单处理 | Formik 的 FieldProps 泛型 |
Element Plus 的 defineComponent |
ReactiveFormsModule 类型检查 |
| 路由参数类型 | React Router 的 useParams 泛型 |
Vue Router 的 defineRoute |
Angular Router 的路由守卫类型 |
六、调试与验证工具
-
类型校验库:
tsimport { z } from "zod"; const schema = z.object({ id: z.string().uuid() }); const data = schema.parse(apiResponse); // 运行时验证 -
类型可视化:
ts// 查看类型定义 type Props = typeof component.props; -
严格模式配置:
json// tsconfig.json { "compilerOptions": { "strictNullChecks": true, "noUncheckedIndexedAccess": true } }
通过遵循框架特性和类型系统规则,开发者可以在 React/Vue/Angular 项目中充分发挥 TypeScript 的优势,同时规避类型相关的潜在风险。建议结合具体业务场景,建立统一的类型规范和代码检查流程。