Typescript中的Type check类型检查
TypeScript 的类型检查是其核心特性之一,它提供了强大的静态类型系统。
1. 基础类型检查
基本类型注解
// 基本类型
let name: string = "John";
let age: number = 30;
let isActive: boolean = true;
let nothing: null = null;
let undef: undefined = undefined;// 数组
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];// 元组
let tuple: [string, number] = ["hello", 42];
2. 对象类型检查
接口(Interface)
interface User {id: number;name: string;email?: string; // 可选属性readonly createdAt: Date; // 只读属性
}const user: User = {id: 1,name: "John",createdAt: new Date()
};// 错误:缺少必需的属性
// const invalidUser: User = { id: 1 }; // Error: Property 'name' is missing// 错误:修改只读属性
// user.createdAt = new Date(); // Error: Cannot assign to 'createdAt'
类型别名(Type Alias)
type Point = {x: number;y: number;
};type ID = number | string;
3. 函数类型检查
// 函数声明
function add(a: number, b: number): number {return a + b;
}// 函数表达式
const multiply: (x: number, y: number) => number = function(x, y) {return x * y;
};// 箭头函数
const divide = (a: number, b: number): number => a / b;// 可选参数和默认参数
function greet(name: string, greeting: string = "Hello"): string {return `${greeting}, ${name}!`;
}// 剩余参数
function sum(...numbers: number[]): number {return numbers.reduce((acc, curr) => acc + curr, 0);
}
4. 联合类型和交叉类型
// 联合类型
type Status = "pending" | "success" | "error";
let currentStatus: Status = "pending";type StringOrNumber = string | number;
let value: StringOrNumber = "hello";
value = 42;// 交叉类型
interface Named {name: string;
}interface Aged {age: number;
}type Person = Named & Aged;
const person: Person = { name: "John", age: 30 };
5. 泛型类型检查
// 泛型函数
function identity<T>(arg: T): T {return arg;
}// 泛型接口
interface Response<T> {data: T;status: number;
}const userResponse: Response<User> = {data: { id: 1, name: "John", createdAt: new Date() },status: 200
};// 泛型约束
interface HasLength {length: number;
}function logLength<T extends HasLength>(arg: T): void {console.log(arg.length);
}
6. 高级类型检查
类型守卫(Type Guards)
function isString(value: any): value is string {return typeof value === "string";
}function processValue(value: string | number) {if (isString(value)) {// TypeScript 知道这里 value 是 string 类型console.log(value.toUpperCase());} else {// TypeScript 知道这里 value 是 number 类型console.log(value.toFixed(2));}
}
keyof 和 typeof
interface User {id: number;name: string;email: string;
}type UserKeys = keyof User; // "id" | "name" | "email"const user = { name: "John", age: 30 };
type UserType = typeof user; // { name: string; age: number; }
7. 严格的类型检查选项
在 tsconfig.json
中启用严格模式:
{"compilerOptions": {"strict": true,"noImplicitAny": true,"noImplicitReturns": true,"noUnusedLocals": true,"noUnusedParameters": true,"exactOptionalPropertyTypes": true,"noImplicitOverride": true}
}
具体严格选项:
strict
: 启用所有严格类型检查选项noImplicitAny
: 禁止隐含的any
类型strictNullChecks
: 严格的 null 检查strictFunctionTypes
: 严格的函数类型检查strictPropertyInitialization
: 严格的属性初始化检查
8. 类型推断
TypeScript 在很多情况下可以自动推断类型:
// 类型推断
let message = "hello"; // 推断为 string 类型
let count = 42; // 推断为 number 类型// 函数返回类型推断
function createUser(name: string, age: number) {return { name, age }; // 推断返回类型为 { name: string; age: number }
}// 上下文类型推断
const buttons = document.querySelectorAll("button");
buttons.forEach(button => {button.addEventListener("click", e => {// e 被推断为 MouseEventconsole.log(e.target);});
});
9. 类型兼容性
TypeScript 使用结构化类型系统:
interface Point {x: number;y: number;
}interface NamedPoint {x: number;y: number;name: string;
}let point: Point = { x: 1, y: 2 };
let namedPoint: NamedPoint = { x: 1, y: 2, name: "origin" };point = namedPoint; // OK: NamedPoint 包含 Point 的所有属性
// namedPoint = point; // Error: Point 缺少 name 属性
10. 实用类型(Utility Types)
interface User {id: number;name: string;email: string;age: number;
}// Partial: 所有属性变为可选
type PartialUser = Partial<User>;// Readonly: 所有属性变为只读
type ReadonlyUser = Readonly<User>;// Pick: 选择部分属性
type UserBasicInfo = Pick<User, "id" | "name">;// Omit: 排除部分属性
type UserWithoutEmail = Omit<User, "email">;// Record: 创建键值对类型
type UserMap = Record<string, User>;
TypeScript 的类型检查系统非常强大,能够在编译时捕获许多常见的错误,提供更好的开发体验和代码质量。