TypeScript基础入门与数据类型
一、TypeScript简介:是什么?为什么用?
1.1 什么是TypeScript?
我们先从一个对比开始:
JavaScript是一门动态类型语言——变量的类型可以随时变化(比如let a = 1; a = “hello”;在JS中完全合法)。
而TypeScript(简称TS)是JavaScript的超集(Superset),它在JS的基础上增加了静态类型系统。
简单说:
- TypeScript = JavaScript + 静态类型检查
- 所有JavaScript代码都是合法的TypeScript代码(TS完全兼容JS)
- TypeScript代码最终会被编译为JavaScript代码(因为浏览器/Node.js只能运行JS)
1.2 为什么需要TypeScript?
为什么要多学一门“TS”?我们用例子看JS的问题和TS的解决方式:
JavaScript的痛点:
// JS中,函数参数类型不固定,容易传错值
function add(a, b) {return a + b;
}// 预期传数字,却传了字符串,结果不符合预期
console.log(add(1, "2")); // 输出 "12"(本应是3)
TypeScript的解决方式:
// TS中,为参数指定类型(number)
function add(a: number, b: number): number {return a + b;
}// 传字符串时,编译阶段就会报错(不用等到运行)
console.log(add(1, "2")); // 报错:Argument of type 'string' is not assignable to parameter of type 'number'
总结TS的核心优势:
- 静态类型检查:在代码编写/编译阶段发现错误,避免运行时崩溃
- 增强代码可读性:类型注解让函数/变量的用途更清晰(比如a: number一眼就知道是数字)
- 提升开发效率:IDE(如VS Code)会基于类型提供自动补全、语法提示
- 更好的可维护性:大型项目中,类型约束能减少代码混乱,方便重构
二、开发环境配置
TypeScript的运行依赖两个核心工具:Node.js(提供运行环境)和TypeScript编译器(tsc)。下面分步配置:
2.1 安装Node.js和npm
Node.js是JavaScript的运行环境,npm是Node.js自带的包管理工具(用于安装TS)。
安装步骤:
- 访问Node.js官网:https://nodejs.org/
- 下载“LTS”版本(长期支持版,更稳定),根据系统(Windows/macOS)选择安装包
- 安装完成后,验证是否成功:
- 打开终端(Windows用CMD/PowerShell,macOS用终端)
- 输入node -v,若输出版本号(如v18.17.0)则Node.js安装成功
- 输入npm -v,若输出版本号(如9.6.7)则npm安装成功
2.2 安装TypeScript编译器(tsc)
TypeScript代码需要通过tsc(TypeScript Compiler)编译为JavaScript。
安装命令(终端中执行):
npm install -g typescript
• -g表示全局安装(全系统可用)
验证安装:
tsc -v
若输出版本号(如Version 5.2.2),则安装成功。
2.3 选择编辑器
推荐使用VS Code(微软开发,对TS支持原生且优秀):
- 下载地址:https://code.visualstudio.com/
- 安装后无需额外配置,默认支持TS语法高亮、类型提示、错误诊断。
三、第一个TypeScript程序:Hello World
3.1 编写TS代码
步骤:
- 新建一个文件夹(比如ts-demo),用于存放代码
- 用VS Code打开该文件夹(菜单栏“文件”→“打开文件夹”)
- 在VS Code左侧“资源管理器”中,右键新建文件,命名为hello.ts(.ts是TypeScript文件的扩展名)
- 写入代码:
// 定义一个字符串变量,类型注解为string
let message: string = "Hello, TypeScript!";// 打印到控制台
console.log(message);
代码解释:
- let message: string:message是变量名,: string是类型注解,表示message必须是字符串类型
- 这行代码的意思是:“声明一个叫message的变量,它只能存储字符串”
3.2 编译TS为JS
TypeScript不能直接运行,需要编译为JavaScript:
- 在VS Code中打开终端(菜单栏“终端”→“新建终端”)
- 输入编译命令:
tsc hello.ts
- 此时文件夹中会生成一个hello.js文件(编译后的JS代码),内容如下:
// 类型注解被移除了(JS不认识类型)
var message = "Hello, TypeScript!";
console.log(message);
3.3 运行JS代码
用Node.js运行编译后的hello.js:
在终端输入:
node hello.js
输出结果:
Hello, TypeScript!
3.4 体验TypeScript的类型检查
故意修改hello.ts,让类型不匹配:
// 尝试给string类型变量赋值数字
let message: string = 123; // 报错:Type 'number' is not assignable to type 'string'
此时VS Code会在代码下方显示红色波浪线,终端执行tsc hello.ts也会报错——这就是TS的静态类型检查在工作,提前阻止错误。
四、TypeScript基础类型
TypeScript提供了多种基础类型,用于约束变量的取值范围。下面逐个讲解:
4.1 原始类型:number、string、boolean
这三种是最常用的原始类型,对应JavaScript中的基本数据类型。
(1)number(数字)
包括整数、浮点数、NaN、Infinity等。
let age: number = 25; // 整数
let height: number = 1.75; // 浮点数
let notANumber: number = NaN; // NaN(特殊的非数字)
let infinity: number = Infinity; // 无穷大
(2)string(字符串)
包括单引号、双引号、模板字符串(反引号)。
let name: string = "Alice"; // 双引号
let hobby: string = 'coding'; // 单引号
let sentence: string =My name is ${name}, I like ${hobby}`; // 模板字符串(可嵌入变量)
(3)boolean(布尔值)
只有true
和false
两个值。
let isStudent: boolean = true;
let hasGraduated: boolean = false;
4.2 数组(array)
数组是一组相同类型的值的集合。TS中定义数组有两种方式:
方式1:类型[]
// 数字数组:只能存放数字
let scores: number[] = [90, 85, 95];// 字符串数组:只能存放字符串
let names: string[] = ["Alice", "Bob"];
方式2:Array<类型>(泛型语法,后续会详细讲)
let scores: Array<number> = [90, 85, 95];
let names: Array<string> = ["Alice", "Bob"];
注意:数组中的元素类型必须一致,否则会报错:
let mix: number[] = [1, "2"]; // 报错:Type 'string' is not assignable to type 'number'
4.3 元组(tuple)
元组是固定长度、固定类型的数组(TS特有的类型)。
比如,存储“姓名+年龄”的组合,长度固定为2,第一个元素是string,第二个是number。
// 定义元组:[string, number]
let person: [string, number] = ["Alice", 25]; // 正确// 错误1:长度不符
let person1: [string, number] = ["Bob"]; // 报错:Source has 1 element(s) but target requires 2// 错误2:类型不符
let person2: [string, number] = [30, "Bob"]; // 报错:Type 'number' is not assignable to type 'string'
元组越界问题:
TS允许给元组添加越界元素(不推荐),但越界元素的类型必须是元组中已有类型的联合类型:
let person: [string, number] = ["Alice", 25];
person.push(30); // 允许(30是number,元组中已有number类型)
person.push("Bob"); // 允许("Bob"是string,元组中已有string类型)
person.push(true); // 报错(boolean不是元组中的类型)
4.4 枚举(enum)
枚举用于定义命名的常量集合,让代码更易读(代替“魔法数字/字符串”)。
基本用法
// 定义枚举:默认从0开始编号(A=0, B=1, C=2)
enum Direction {Up,Down,Left,Right
}// 使用枚举
let move: Direction = Direction.Up;
console.log(move); // 输出0(Up的默认值)
自定义枚举值
可以手动指定枚举成员的值(数字或字符串):
// 数字枚举:从1开始编号(A=1, B=2, C=3)
enum Level {Low = 1,Medium,High
}// 字符串枚举:每个成员必须手动赋值
enum Status {Success = "success",Error = "error",Pending = "pending"
}console.log(Level.Medium); // 输出2
console.log(Status.Success); // 输出"success"
枚举的优势:
用Direction.Up比直接写0更易读,且修改值时只需改枚举定义,无需改使用处。
4.5 any(任意类型)
any表示“任意类型”,变量被声明为any后,TS会关闭对它的类型检查(相当于回到JS的动态类型)。
使用场景:
- 处理动态数据(比如从API获取的未知结构数据)
- 迁移JS项目到TS时,临时兼容未确定类型的代码
let data: any = "hello";
data = 123; // 允许(any类型可以赋值任何类型)
data = true; // 允许// 调用任意方法也不会报错(即使方法不存在)
data.toUpperCase(); // 不报错(运行时若data不是字符串会崩溃)
data.foo(); // 不报错(运行时会报错)
注意:谨慎使用any!过度使用会失去TS的类型检查优势。
4.6 void(无返回值)
void用于表示函数没有返回值(即函数执行后不返回任何值)。
// 函数没有return语句,返回值类型为void
function logMessage(message: string): void {console.log(message);
}// 函数return undefined,也可以用void(undefined是void的子类型)
function doNothing(): void {return undefined;
}
注意:void只能用于函数返回值,不能用于变量(变量用undefined)。
4.7 null和undefined
null表示“空值”,undefined表示“未定义”(JS原生值)。
在TS中,默认情况下null和undefined是所有类型的子类型(可以赋值给任何类型):
let num: number = null; // 默认允许
let str: string = undefined; // 默认允许
若开启strictNullChecks配置(推荐),null和undefined只能赋值给any或自身类型:
// 开启strictNullChecks后
let n: null = null; // 正确
let u: undefined = undefined; // 正确
let num: number = null; // 报错:Type 'null' is not assignable to type 'number'
4.8 never(永不存在的值)
never表示“永不存在的类型”,用于描述:
- 抛出错误的函数(永远不会执行完)
- 无限循环的函数(永远不会返回)
// 抛出错误的函数:永远不会返回,返回值类型为never
function throwError(message: string): never {throw new Error(message);
}// 无限循环的函数:永远不会返回,返回值类型为never
function infiniteLoop(): never {while (true) {// 循环不会结束}
}
never与void的区别:
- void表示“返回undefined”(函数正常结束)
- never表示“函数永远不会结束”
4.9 类型推断
TS有类型推断功能:如果变量声明时赋值,且没有显式指定类型,TS会自动推断类型。
let age = 25; // 推断为number类型(等价于let age: number = 25)
let name = "Alice"; // 推断为string类型age = "25"; // 报错:Type 'string' is not assignable to type 'number'(推断的类型会被严格遵守)
类型推断让代码更简洁:不需要给每个变量都写类型注解(显式注解仅在推断不准确时使用)。
五、编译配置与技巧
5.1 自动编译(watch模式)
每次修改TS文件后手动执行tsc filename.ts很麻烦,可用watch模式自动编译:
tsc hello.ts --watch
启用后,修改hello.ts并保存,TS会自动重新编译为hello.js。
5.2 多文件编译与tsconfig.json
当项目有多个TS文件时,逐个编译效率低。此时可以用tsconfig.json配置编译选项:
-
在项目根目录执行tsc --init,生成默认的tsconfig.json
-
核心配置项(简化版):
{"compilerOptions": {"target": "ES6", // 编译后的JS版本(如ES5、ES6)"module": "CommonJS", // 模块系统(如CommonJS、ES6)"outDir": "./dist", // 编译后JS文件的输出目录"rootDir": "./src", // TS源文件的根目录"strict": true // 开启严格模式(推荐,包括strictNullChecks等)},"include": ["./src/**/*"], // 需要编译的TS文件(**表示所有子目录,*表示所有文件)"exclude": ["node_modules"] // 排除的文件/目录
}
- 配置完成后,终端执行tsc(无需指定文件名),会自动编译src目录下的所有TS文件到dist目录。
六、总结
本文我们学习了:
- TypeScript是JS的超集,核心是静态类型系统,能提前发现错误
- 环境配置:安装Node.js → 安装TS → 用VS Code编写代码
- 第一个程序:hello.ts → 编译为hello.js → 用Node运行
- 基础类型:包括number、string、boolean、array、tuple、enum、any、void、null、undefined、never
- 类型推断和编译技巧(watch模式、tsconfig.json)