跳转至

语法基础

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 能根据赋值自动推断变量类型,无需每次都显式标注:

1
2
3
4
5
6
7
8
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 不强制要求分号结尾,但建议保持团队一致:

1
2
3
// 两种写法都合法
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,
}

类型优先原则

1
2
3
4
5
6
// 尽量使用更精确的类型,避免 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 模式下)

空值检查

1
2
3
4
5
6
7
function getLength(s: string | null): number {
  // 需要先检查 null
  if (s === null) {
    return 0;
  }
  return s.length;
}

小结

本章介绍了 TypeScript 的基础语法和核心类型概念,包括:

  • 变量声明letconst 的正确使用
  • 类型注解:为变量和函数标注类型
  • 基本类型:原始类型、数组、元组、枚举
  • 类型推断:让编译器自动推导类型
  • 联合类型与类型别名:灵活组合类型
  • 命名规范与代码风格:保持代码一致

掌握这些基础语法是学习 TypeScript 的第一步,为后续深入理解接口、泛型等高级特性打下坚实基础。