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 场景,后续可再深入泛型、装饰器、高级类型等内容。

相关推荐
2分钟速写快排4 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60615 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角6 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!6 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰6 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
Interview Aid1126 小时前
Walmart Global Tech SDE 三轮面经|基础、并发、压力面
面试·职场和发展
mayaairi8 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen8 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马9 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒9 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端