TypeScript 核心基础知识

TypeScript(简称 TS)作为 JavaScript 的超集,已成为前端工程化的标配。它通过静态类型检查,提前规避大量运行时错误,让代码更易维护、更具可读性。本文抛开复杂概念,从新手视角梳理 TS 核心基础知识,看完就能上手写 TS 代码。

一、为什么要学 TypeScript?

先明确学习的意义,避免盲目跟风:

  1. 静态类型检查:编码阶段发现错误(如类型不匹配、属性不存在),而非运行时崩溃;
  2. 更好的代码提示:VS Code 等编辑器能精准提示变量 / 函数的属性和方法,提升开发效率;
  3. 代码可读性提升:类型注解就是 "自文档",一眼看懂变量 / 函数的用途;
  4. 工程化必备:Vue3、React、Node.js 主流框架 / 环境均推荐 / 支持 TS,大厂项目标配。

二、TS 环境搭建(快速上手)

1. 安装 TypeScript

js 复制代码
# 全局安装 TS 编译器
npm install -g typescript
# 验证安装(查看版本)
tsc -v

2. 第一个 TS 程序

  • 创建 hello.ts 文件:

    ts 复制代码
    // 类型注解:指定变量类型为字符串
    const message: string = "Hello TypeScript!";
    console.log(message);
  • 编译 TS 为 JS:

    ts 复制代码
    # 将 hello.ts 编译为 hello.js
    tsc hello.ts
  • 运行 JS 文件:

    ts 复制代码
    node hello.js

3. 简化开发:自动编译 + 热更新(可选)

ts 复制代码
# 安装 ts-node(直接运行 TS,无需手动编译)
npm install -g ts-node
# 直接运行 TS 文件
ts-node hello.ts

三、核心基础:类型注解与类型推断

1. 类型注解(手动指定类型)

语法:变量名: 类型 = 值,告诉 TS 变量的具体类型。

ts 复制代码
// 基本类型注解
let name: string = "张三"; // 字符串
let age: number = 25; // 数字(整数/浮点数/NaN/Infinity)
let isAdult: boolean = true; // 布尔值
let empty: null = null; // null
let undef: undefined = undefined; // undefined

// 数组注解(两种写法)
let arr1: string[] = ["苹果", "香蕉"]; // 推荐
let arr2: Array<number> = [1, 2, 3]; // 泛型写法

// 对象注解
let user: { name: string; age: number } = {
  name: "李四",
  age: 30,
};

// 函数注解(参数 + 返回值)
function add(a: number, b: number): number {
  return a + b;
}

2. 类型推断(TS 自动推导类型)

TS 会根据变量的初始值自动推断类型,无需手动注解(日常开发中优先用推断,减少冗余)。

typescript

运行

ts 复制代码
let str = "hello"; // TS 自动推断 str 为 string 类型
str = 123; // 报错:不能将类型"number"分配给类型"string"

let num = 100; // 推断为 number 类型
let bool = false; // 推断为 boolean 类型

核心原则:能靠推断的就不手动注解,需要明确约束时才加注解。

四、常用基础类型

1. 原始类型

表格

类型 说明 示例
string 字符串 let str: string = "TS"
number 数字 let num: number = 666
boolean 布尔值 let flag: boolean = false
null 空值 let n: null = null
undefined 未定义 let u: undefined = undefined
symbol 唯一值 let s: symbol = Symbol("id")
bigint 大整数 let b: bigint = 100n

2. 数组

两种写法,推荐第一种:

ts 复制代码
// 写法1:类型[]
let numbers: number[] = [1, 2, 3];
// 写法2:Array<类型>
let strings: Array<string> = ["a", "b"];
// 禁止混合类型(除非指定联合类型)
let mix: (string | number)[] = [1, "a"]; // 联合类型:字符串或数字

3. 元组(Tuple)

固定长度、固定类型的数组(强约束):

ts 复制代码
// 元组注解:第一个元素是string,第二个是number
let tuple: [string, number] = ["张三", 25];
tuple[0] = "李四"; // 合法
tuple[1] = 30; // 合法
tuple.push(3); // 注意:push 不会报错(TS 设计缺陷),但访问 tuple[2] 会报错

4. 任意类型(any)

关闭 TS 类型检查,慎用(失去 TS 核心价值):

ts 复制代码
let anyValue: any = "hello";
anyValue = 123; // 不报错
anyValue = true; // 不报错
anyValue.foo(); // 不报错(运行时可能崩溃)

5. 未知类型(unknown)

安全版 any,必须先类型校验才能使用:

ts 复制代码
let unknownValue: unknown = "hello";
// unknownValue.toUpperCase(); // 报错:不能直接调用方法

// 先校验类型,再使用
if (typeof unknownValue === "string") {
  unknownValue.toUpperCase(); // 合法
}

6. 空类型(void)

表示函数没有返回值(或返回 undefined):

ts 复制代码
function logMsg(): void {
  console.log("这是一个无返回值的函数");
  // 省略 return 或 return undefined 均合法
}

7. 永不类型(never)

表示永远不会发生的值(如抛出错误、无限循环):

ts 复制代码
// 抛出错误的函数,返回值为 never
function throwError(): never {
  throw new Error("出错了!");
}

// 无限循环的函数,返回值为 never
function infiniteLoop(): never {
  while (true) {}
}

五、进阶基础:接口与类型别名

1. 接口(interface)

用于约束对象的结构,可扩展、可实现,是 TS 中定义对象类型的核心方式:

ts 复制代码
// 定义接口
interface User {
  name: string; // 必选属性
  age: number; // 必选属性
  gender?: string; // 可选属性(加 ?)
  readonly id: number; // 只读属性(不可修改)
}

// 使用接口约束对象
let user: User = {
  name: "张三",
  age: 25,
  id: 1001,
  // gender 可选,可省略
};

user.id = 1002; // 报错:只读属性不能修改

2. 类型别名(type)

给类型起别名,适用范围更广(可约束任意类型,不止对象):

ts 复制代码
// 基本类型别名
type Str = string;
let str: Str = "hello";

// 对象类型别名
type User = {
  name: string;
  age: number;
};

// 联合类型别名
type NumberOrString = number | string;
let value: NumberOrString = 100;
value = "abc";

3. interface vs type 核心区别

表格

特性 interface type
扩展 可通过 extends 扩展 可通过 & 交叉扩展
重复定义 支持(自动合并) 不支持(会报错)
适用范围 主要约束对象 / 类 可约束任意类型(基本类型、联合类型等)

使用建议 :定义对象 / 类的结构用 interface,其他场景用 type

六、函数相关类型

1. 函数参数与返回值注解

ts 复制代码
// 普通函数
function sum(a: number, b: number): number {
  return a + b;
}

// 箭头函数
const multiply = (a: number, b: number): number => {
  return a * b;
};

// 无返回值
const log = (msg: string): void => {
  console.log(msg);
};

2. 可选参数与默认参数

ts 复制代码
// 可选参数(加 ?,必须放在必选参数后面)
function greet(name: string, age?: number): void {
  console.log(`姓名:${name},年龄:${age || "未知"}`);
}
greet("张三"); // 合法
greet("李四", 30); // 合法

// 默认参数(自动推断类型,无需加 ?)
function sayHi(name: string = "游客"): void {
  console.log(`你好,${name}`);
}
sayHi(); // 输出:你好,游客

3. 函数类型别名

定义函数的 "形状"(参数类型 + 返回值类型):

ts 复制代码
// 定义函数类型
type AddFn = (a: number, b: number) => number;

// 实现函数
const add: AddFn = (x, y) => {
  return x + y;
};

七、类型守卫

通过代码逻辑缩小类型范围,让 TS 更精准推断类型:

ts 复制代码
// typeof 类型守卫(适用于原始类型)
function printValue(value: string | number) {
  if (typeof value === "string") {
    console.log(value.toUpperCase()); // TS 知道这里 value 是 string
  } else {
    console.log(value.toFixed(2)); // TS 知道这里 value 是 number
  }
}

// instanceof 类型守卫(适用于类实例)
class Animal {}
class Dog extends Animal {
  bark() {
    console.log("汪汪汪");
  }
}

function judgeAnimal(animal: Animal) {
  if (animal instanceof Dog) {
    animal.bark(); // TS 知道这里 animal 是 Dog 实例
  }
}

八、TS 配置文件(tsconfig.json)

项目中通过 tsconfig.json 配置 TS 编译规则,执行 tsc --init 生成默认配置,核心配置说明:

json 复制代码
{
  "compilerOptions": {
    "target": "ES6", // 编译目标 JS 版本(ES5/ES6/ESNext)
    "module": "ESNext", // 模块系统(CommonJS/ESModule)
    "outDir": "./dist", // 编译后的 JS 文件输出目录
    "rootDir": "./src", // 源文件目录
    "strict": true, // 开启严格模式(推荐,强制类型检查)
    "noImplicitAny": true, // 禁止隐式 any 类型
    "esModuleInterop": true // 兼容 CommonJS 和 ESModule
  },
  "include": ["./src/**/*"], // 要编译的文件
  "exclude": ["node_modules"] // 排除的文件
}

九、新手避坑指南

  1. 不要滥用 any :用 unknown 替代 any,保留类型检查;
  2. 可选参数放最后:TS 要求可选参数必须在必选参数之后;
  3. 元组 push 不报错:元组虽固定长度,但 push 不会触发 TS 报错,需手动规避;
  4. 严格模式必开strict: true 能暴露更多潜在问题,是 TS 核心价值所在;
  5. 类型断言要谨慎as 语法是 "告诉 TS 我比你更清楚类型",滥用会导致类型不安全。

总结

  1. TS 核心是静态类型系统,通过类型注解 / 推断提前规避错误;
  2. 常用基础类型:原始类型、数组、元组、any/unknown、void/never,需掌握各自使用场景;
  3. 定义对象结构优先用 interface,其他类型约束用 type
  4. 函数注解要关注参数、返回值、可选参数,类型守卫能提升类型推断精度;
  5. 项目中务必开启严格模式(strict: true),发挥 TS 最大价值。

从 JS 过渡到 TS 无需一步到位,可先在项目中局部使用,逐步覆盖,重点是理解 "类型" 的核心思想,而非死记语法。掌握本文的基础知识,足以应对日常开发中 80% 的 TS 场景,后续可再深入泛型、装饰器、高级类型等内容。

相关推荐
Filotimo_1 小时前
Vue 选项式 API vs 组合式 API:区别全解析
前端·javascript·vue.js
文心快码BaiduComate2 小时前
百度文心快码全面支持GLM-5
前端·人工智能
unirst19850072 小时前
使用vite打包并部署vue项目到nginx
前端·vue.js·nginx
wordbaby2 小时前
Vue 实战:从零实现“划词标注”与“高亮笔记”功能
前端
上海合宙LuatOS2 小时前
LuatOS核心库API——【fatfs】支持FAT32文件系统
java·前端·网络·数据库·单片机·嵌入式硬件·物联网
wuhen_n2 小时前
JavaScript 手写 new 操作符:深入理解对象创建
前端·javascript
派星2 小时前
Day02:认识 AI IDE 工具
前端·人工智能
m0_528749002 小时前
linux编程----目录流
java·前端·数据库
集成显卡2 小时前
前端视频播放方案选型:主流 Web 播放器对比 + Vue3 实战
前端·vue·音视频