声明类型后TS就会进行类型检测,声明的类型可以称为类型注解(Type Annotation)
var/ let/ const 标识符:数据类型 = 赋值
我们来梳理一下 TypeScript 中常用的所有类型注解(或者说可以用于类型注解的类型)。TypeScript 的类型系统非常丰富,这里会涵盖基础类型、对象类型、函数类型以及一些特殊的和高级的类型。
1. 基础(原始)类型 (Basic Primitive Types)
这些是 JavaScript 中最基本的数据类型。
-
string: 表示文本数据(字符串)。
tslet message: string = "Hello World";
-
number: 表示数字,包括整数和浮点数。
tslet count: number = 10; let price: number = 99.99;
-
boolean: 表示逻辑值 true 或 false。
tslet isActive: boolean = true;
-
null: 表示一个有意的"无"对象值。
tslet data: null = null; // 通常在联合类型中使用,如 string | null
-
undefined: 表示一个未初始化的值。
tslet notAssigned: undefined = undefined; // 通常在联合类型中使用
-
symbol: 表示全局唯一的引用值(ES6+)。
tslet sym: symbol = Symbol("key");
-
bigint: 表示任意精度的整数(ES2020+)。需要 target 编译选项设置为 ES2020 或更高。
tslet largeNumber: bigint = 9007199254740991n;
2. 对象类型 (Object Types)
-
object: 表示非原始类型(即除了 string, number, boolean, symbol, null, undefined, bigint 之外的类型)。过于宽泛,不常用。
tslet obj: object = { name: "Alice" }; obj = [1, 2, 3]; // 数组也是 object obj = () => {}; // 函数也是 object
-
对象字面量类型 (Object Literal Types) : 直接描述对象的结构。
tslet person: { name: string; age: number; isActive?: boolean }; // ?表示可选属性 person = { name: "Bob", age: 30 }; person = { name: "Charlie", age: 25, isActive: true };
-
接口 (Interfaces) : 定义对象的结构契约,可复用。
tsinterface Point { readonly x: number; // readonly 表示只读属性 y: number; } let p1: Point = { x: 10, y: 20 }; // p1.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.
-
类型别名 (Type Aliases) : 给类型起一个新名字,也可用于对象、联合类型、元组等。
tstype UserID = string | number; type User = { id: UserID; username: string }; let user1: User = { id: 123, username: "admin" }; let user2: User = { id: "abc", username: "guest" };
3. 数组类型 (Array Types)
-
Type[] : 表示元素类型为 Type 的数组。
tslet numbers: number[] = [1, 2, 3]; let names: string[] = ["Alice", "Bob"];
-
Array (泛型语法) : 与 Type[] 等价。
tslet scores: Array<number> = [100, 95, 88]; let flags: Array<boolean> = [true, false];
-
元组类型 (Tuple Types) : 表示一个已知元素数量和类型的数组,各元素类型不必相同。
tslet employee: [string, number, boolean]; // 姓名, 年龄, 是否在职 employee = ["Alice", 30, true]; // employee = ["Bob", 35]; // Error: Type '[string, number]' is not assignable to type '[string, number, boolean]'. // employee = [30, "Charlie", false]; // Error: Type 'number' is not assignable to type 'string'. // 可选元组元素 (?) let optionalTuple: [string, number?]; optionalTuple = ["Dave"]; optionalTuple = ["Eve", 28]; // 剩余元组元素 (...) let colors: [string, ...number[]] = ["red", 255, 0, 0];
4. 函数类型 (Function Types)
描述函数的参数类型和返回值类型。
-
完整函数类型注解: (param1: Type1, param2: Type2, ...) => ReturnType
tslet add: (x: number, y: number) => number; add = (a, b) => { return a + b; }; let log: (message: string, code?: number) => void; // ?表示可选参数, void表示无返回值 log = (msg) => console.log(msg); log = (msg, code) => console.log(`[${code}] ${msg}`); // 带剩余参数 let sum: (...nums: number[]) => number; sum = (...args) => args.reduce((acc, curr) => acc + curr, 0);
-
在函数声明或表达式中注解:
tsfunction multiply(a: number, b: number): number { // 参数和返回值注解 return a * b; } const divide = (x: number, y: number): number => { if (y === 0) throw new Error("Division by zero"); return x / y; };
5. 特殊类型 (Special Types)
-
any : 表示任意类型。应尽量避免使用,因为它会绕过 TypeScript 的类型检查。
tslet notSure: any = 4; notSure = "maybe a string instead"; notSure = false; // Okay, definitely not a boolean. notSure.toFixed(); // Okay, if it's a number, but may crash if not.
-
unknown: 表示未知类型。是 any 的类型安全版本。在使用 unknown 类型的变量前,必须进行类型检查或类型断言来缩小其范围。
tslet maybe: unknown; maybe = "hello"; // console.log(maybe.length); // Error: Object is of type 'unknown'. if (typeof maybe === "string") { console.log(maybe.length); // Okay, type narrowed to string }
-
void: 表示函数没有返回值(或者说返回 undefined)。
tsfunction warnUser(): void { console.log("This is my warning message"); } let unusable: void = undefined; // 只能赋值为 undefined 或 null (如果 strictNullChecks 关闭)
-
never: 表示永远不会有返回值的类型。例如,总是抛出异常的函数或永远不会结束的函数(如无限循环)。
tsfunction error(message: string): never { throw new Error(message); } function infiniteLoop(): never { while (true) {} }
6. 字面量类型 (Literal Types)
表示一个具体的值作为类型。
-
字符串字面量类型:
tslet direction: "left" | "right" | "up" | "down"; direction = "left"; // direction = "center"; // Error: Type '"center"' is not assignable to type '"left" | "right" | "up" | "down"'.
-
数字字面量类型:
tslet status: 0 | 1 | 2; status = 1; // status = 3; // Error
-
布尔字面量类型:
tslet result: true; result = true; // result = false; // Error
7. 联合类型 (Union Types)
使用 | 分隔,表示一个值可以是几种类型之一。
ts
let id: number | string;
id = 101;
id = "abc";
// id = false; // Error
function printPadding(padding: number | string): string {
if (typeof padding === "number") {
return " ".repeat(padding); // padding is number here
}
return padding; // padding is string here
}
8. 交叉类型 (Intersection Types)
使用 & 分隔,表示一个值必须同时满足多种类型的特征。常用于合并对象类型。
ts
interface Draggable {
drag(): void;
}
interface Resizable {
resize(): void;
}
type UIWidget = Draggable & Resizable;
let widget: UIWidget = {
drag: () => console.log("Dragging..."),
resize: () => console.log("Resizing...")
};
widget.drag();
widget.resize();
9. enum 类型 (Enums)
用于定义一组命名的常量(枚举)。
-
数字枚举:
tsenum Direction { Up, Down, Left, Right } // 默认为 0, 1, 2, 3 let dir: Direction = Direction.Left; // dir is 2
-
字符串枚举:
tsenum LogLevel { Error = "ERROR", Warn = "WARN", Info = "INFO" } let level: LogLevel = LogLevel.Info; // level is "INFO"
10. 类类型 (Class Types)
类本身既是值(可以创建实例),也是类型(可以用于类型注解)。
ts
class Animal {
name: string;
constructor(name: string) { this.name = name; }
move(distance: number = 0): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
let dog: Animal = new Animal("Buddy");
dog.move(10);
// 构造函数签名类型 (较少直接使用)
type AnimalConstructor = new (name: string) => Animal;
function createAnimal(ctor: AnimalConstructor, name: string): Animal {
return new ctor(name);
}
let cat = createAnimal(Animal, "Whiskers");
注意:
-
类型推断 (Type Inference): TypeScript 可以在很多情况下自动推断出类型,这时类型注解是可选的。
tslet inferredString = "I am a string"; // TS推断为 string let inferredNumber = 42; // TS推断为 number
-
高级类型: TypeScript 还有更高级的类型,如泛型 (Generics) (Type)、条件类型 (Conditional Types) (T extends U ? X : Y)、映射类型 (Mapped Types) ({[P in K]: T})、索引类型 (Index Types) (keyof, T[K]) 等,它们通常用于创建更灵活和可复用的类型,或者从现有类型派生新类型。
