语法基础
TypeScript 是 JavaScript 的超集,在保留 JavaScript 灵活性的同时增加了静态类型系统。本章将介绍 TypeScript 的基本语法规则和核心类型概念。
变量声明
TypeScript 支持三种变量声明方式,它们的区别主要在于作用域和可变性:
| // var:函数级作用域,不推荐在现代代码中使用
var oldWay = "avoid this";
// let:块级作用域变量,可重新赋值
let message: string = "Hello, TypeScript!";
message = "Hi again"; // ✅ 可以重新赋值
// const:块级作用域常量,不可重新赋值
const PI: number = 3.14159;
// PI = 3; // ❌ 编译错误:无法分配到常量
|
声明规则:
- 优先使用
const,只有当变量需要重新赋值时才使用 let - 避免使用
var(它有函数级作用域和变量提升等令人困惑的行为) - 声明时尽量显式标注类型(或让 TypeScript 自动推断)
类型注解
TypeScript 的核心特性是类型注解,可以为变量、函数参数和返回值标注类型,让编译器在编译阶段检查类型错误。
| // 变量类型注解
let username: string = "Alice";
let age: number = 25;
let isActive: boolean = true;
// 函数参数和返回值类型注解
function add(a: number, b: number): number {
return a + b;
}
let result: number = add(1, 2); // 正确
// let error: string = add(1, 2); // 编译错误:类型 'number' 不可赋值给 'string'
|
基本类型系统
TypeScript 提供了丰富的内置类型:
原始类型
| // 字符串
let name: string = "TypeScript";
// 数字(所有数字都是浮点数,没有单独的 int)
let count: number = 42;
let price: number = 3.14;
// 布尔值
let done: boolean = false;
// null 和 undefined
let n: null = null;
let u: undefined = undefined;
// void(通常用于函数无返回值)
function log(message: string): void {
console.log(message);
}
|
特殊类型
| // any:关闭类型检查,尽量少用
let loose: any = 4;
loose = "can be anything"; // ✅ 不会报错
// unknown:类型安全的 any,使用前需要类型检查
let uncertain: unknown = 4;
uncertain = "hello";
// uncertain.toFixed(); // ❌ 错误:不能直接调用方法
if (typeof uncertain === "number") {
uncertain.toFixed(); // ✅ 类型收窄后可调用
}
// never:永远不会发生的值
function throwError(message: string): never {
throw new Error(message);
}
|
数组和元组
| // 数组两种写法
let list1: number[] = [1, 2, 3];
let list2: Array<string> = ["a", "b", "c"];
// 只读数组
let readonlyList: ReadonlyArray<number> = [1, 2, 3];
// readonlyList[0] = 10; // ❌ 不能修改
// 元组:固定长度和类型的数组
let tuple: [string, number] = ["Alice", 25];
// tuple = [25, "Alice"]; // ❌ 类型顺序不匹配
tuple.push("extra"); // ✅ 注意:push 仍被允许(设计上的权衡)
|
枚举
| // 数字枚举(默认从 0 开始)
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
// 字符串枚举
enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
let dir: Direction = Direction.Up;
console.log(dir); // 0
console.log(Direction[0]); // "Up"
|
类型推断
TypeScript 能根据赋值自动推断变量类型,无需每次都显式标注:
| let x = 10; // 自动推断为 number
let message = "Hi"; // 自动推断为 string
let flag = true; // 自动推断为 boolean
// 函数返回值类型推断
function multiply(a: number, b: number) {
return a * b; // 自动推断返回值为 number
}
|
联合类型和类型别名
| // 联合类型:变量可以是多种类型之一
let id: string | number;
id = "abc123"; // ✅
id = 123; // ✅
// id = true; // ❌ 布尔值不在联合类型中
// 类型别名:为复杂类型命名
type Point = {
x: number;
y: number;
};
type ID = string | number;
let origin: Point = { x: 0, y: 0 };
let userId: ID = "user-001";
|
基本语法规则
分号
TypeScript 不强制要求分号结尾,但建议保持团队一致:
| // 两种写法都合法
let a = 1;
let b = 2 // 无分号也可以
|
注释
| // 单行注释
/*
* 多行注释
*/
/**
* 文档注释(用于生成 API 文档)
* @param name 用户名
* @returns 问候语
*/
function greet(name: string): string {
return `Hello, ${name}!`;
}
|
代码块和语句
| // 使用 {} 包裹代码块
if (true) {
console.log("Hello!");
}
// 一行一个语句(推荐)
let x = 1;
let y = 2;
// 表达式语句
x++;
console.log(x);
|
代码风格建议
命名规范
| // 变量和函数:camelCase
let userName = "Alice";
function getUserName() { }
// 类型和接口:PascalCase
type UserRole = "admin" | "user";
interface UserProfile { name: string }
// 枚举:PascalCase,值用 UPPER_CASE
enum HttpStatus {
OK = 200,
NOT_FOUND = 404,
}
|
类型优先原则
| // 尽量使用更精确的类型,避免 any
// ❌ 不推荐
function process(data: any): any { }
// ✅ 推荐
function process<T>(data: T): T { }
|
常见错误
类型不匹配
| let count: number = 5;
// count = "hello"; // ❌ 类型 '"hello"' 不可赋值给 'number'
|
未赋值的变量
| let name: string;
// console.log(name); // ❌ 使用前未赋值(在 strict 模式下)
|
空值检查
| function getLength(s: string | null): number {
// 需要先检查 null
if (s === null) {
return 0;
}
return s.length;
}
|
小结
本章介绍了 TypeScript 的基础语法和核心类型概念,包括:
- 变量声明:
let 和 const 的正确使用 - 类型注解:为变量和函数标注类型
- 基本类型:原始类型、数组、元组、枚举
- 类型推断:让编译器自动推导类型
- 联合类型与类型别名:灵活组合类型
- 命名规范与代码风格:保持代码一致
掌握这些基础语法是学习 TypeScript 的第一步,为后续深入理解接口、泛型等高级特性打下坚实基础。