TypeScript类型系统:从原始到对象的实战精要
1.原始类型与对象类型
原始类型
关键内容点
- JavaScript 原始类型映射:
number
、string
、boolean
、null
、undefined
、symbol
、bigint
在 TypeScript 中对应同名类型注解,null
/undefined
在strictNullChecks
开启时非其他类型子类型。 - void 类型:标记无有效返回值的函数,实际返回
undefined
,与 JS 的void
操作符语义不同。
// null/undefined 类型标注(strictNullChecks 开启时)
const nul: null = null;
const undef: undefined = undefined;
const str: string = null; // 报错:类型“null”不能分配给类型“string” // void 函数返回值
function logName(name: string): void { console.log(name); // 无显式返回值,类型为 void
}
数组与元组
关键内容点
- 数组类型:
T[]
或Array<T>
,支持泛型,如string[]
表示字符串数组。 - 元组(Tuple):
- 固定长度、位置类型严格绑定,如
[string, number]
。 - 可选元素(
?
)和具名元组(TypeScript 4.0+,为元素添加标签)。 - 越界访问时触发类型错误,解构赋值时校验元素数量。
- 固定长度、位置类型严格绑定,如
// 普通数组 vs 元组
const arr: string[] = ['a', 'b']; // 可动态扩展
const tuple: [string, number] = ['lin', 24]; // 固定长度 2,类型严格绑定 // 具名元组(提升可读性)
const userTuple: [name: string, age: number] = ['linbudu', 28];
console.log(userTuple.name); // 合法,类型为 string // 可选元素与越界报错
const optionalTuple: [string, number?, boolean?] = ['hello'];
optionalTuple[1] = 10; // 合法
console.log(optionalTuple[3]); // 报错:索引 3 超出元组长度
对象类型
关键内容点
- interface 接口定义:
- 规范对象属性类型,支持可选属性(
?
)和只读属性(readonly
)。 - 类型检查严格:属性不能多/少,赋值需匹配类型。
- 规范对象属性类型,支持可选属性(
- type 与 interface 区别:
interface
用于定义对象/类结构,type
用于创建类型别名(如联合类型、函数类型)。
- 特殊对象类型:
object
:非原始类型(数组、对象、函数),避免使用Object
(装箱类型)和{}
(空对象)。
// interface 定义对象结构(可选/只读属性)
interface IUser { readonly name: string; // 只读属性,不可重新赋值 age: number; email?: string; // 可选属性
}
const user: IUser = { name: 'lin', age: 24 };
user.name = 'newName'; // 报错:只读属性不能修改
user.email = 'test@example.com'; // 合法 // type 定义函数类型与联合类型
type Func = (x: number) => string;
type ID = string | number; // object 与 Object 的区别
const obj: object = { key: 'value' }; // 合法,非原始类型
const badObj: Object = 123; // 不推荐,装箱类型包含所有原始类型
类型系统核心概念与最佳实践
关键内容点
- 严谨性优势:
- 元组防止越界访问,
readonly
修饰符编译时校验不可变属性。 strictNullChecks
避免null
/undefined
隐式赋值风险。
- 元组防止越界访问,
- 与 JavaScript 的差异:
- TypeScript 的
void
是类型层面的“无返回值”,JS 的void
是操作符(返回undefined
)。 - 元组是 TS 特有的强类型定长数组,JS 无此概念。
- TypeScript 的
// 元组用于固定结构数据(如坐标)
const point: [number, number] = [10, 20]; // 明确 x/y 坐标类型,避免越界 // readonly 修饰数组(禁止修改原数组)
const readonlyArr: readonly string[] = ['a', 'b'];
readonlyArr.push('c'); // 报错:类型“readonly string[]”上不存在属性“push” // 避免使用 {},推荐 Record<string, unknown>
const safeObj: Record<string, unknown> = { key: 'value' };
safeObj.unknownProp = 123; // 合法,但类型安全(值为 unknown)
总结
通过 原始类型标注、元组的定长类型约束、对象接口的属性修饰 等特性,TypeScript 实现了比 JavaScript 更严格的类型检查,提升代码可靠性。案例演示了如何利用这些特性解决实际开发中的类型安全问题,如数据结构约束、属性不可变性、跨类型赋值校验等。后续可进一步学习字面量类型、枚举、泛型等进阶内容,深化类型系统应用。