语言基础
# 01.语言基础
# 目录介绍
- 01.TypeScript介绍
- 1.1 类型检查
- 1.2 提示和可读性
- 1.3 面向对象
- 1.4 模块化
- 1.5 渐进式采用
- 1.6 更早错误检测
- 1.7 总结一下
- 02.变量和常量
- 2.1 变量名
- 2.2 变量声明
- 2.3 常量
- 03.数据类型
- 3.1 布尔类型
- 3.2 数字类型
- 3.3 字符串类型
- 3.4 元组类型
- 3.5 枚举类型
- 3.6 任意类型
- 3.7 空类型
- 3.8 未知类型
- 3.9
never类型
- 04.数组
- 4.1 基础数组类型
- 4.2 混合类型数组
- 4.3 只读数组
- 05.函数
- 5.1 函数声明
- 5.2 函数参数
- 5.3 函数返回值
- 5.4 函数重载
- 5.5 函数类型
- 5.6 泛型函数
- 5.7 异步函数
- 5.8 函数类型推断
- 5.9 函数类型守卫
# 01.TypeScript介绍
TypeScript 是一种基于 JavaScript 的强类型编程语言,它通过静态类型检查增强了 JavaScript 的开发体验。
TypeScript 是 JavaScript 的超集,它在 JavaScript 的基础上增加了静态类型检查和面向对象编程等特性。
尽管 JavaScript 已经非常强大且广泛使用,但 TypeScript 的出现解决了 JavaScript 在大型项目开发中的一些痛点。
# 1.1 类型检查
JavaScript 是动态类型语言,变量的类型在运行时才能确定。这会导致以下问题:
- 类型错误:只有在运行时才能发现类型不匹配的问题。
- 代码可维护性差:在大型项目中,难以追踪变量的类型和结构。
TypeScript 引入了静态类型检查,可以在编译时捕获类型错误,提高代码的健壮性。
function add(a: number, b: number): number {
return a + b;
}
add(1, 2); // 正确
add("1", 2); // 编译时报错:Argument of type 'string' is not assignable to parameter of type 'number'.
2
3
4
5
6
# 1.2 提示和可读性
JavaScript 缺乏类型信息,IDE 无法提供准确的代码提示,开发效率较低。
TypeScript 提供了丰富的类型信息,IDE 可以根据类型推断提供智能提示,提升开发效率。
interface User {
id: number;
name: string;
}
function getUser(): User {
return { id: 1, name: "John" };
}
const user = getUser();
console.log(user.name); // IDE 会提示 name 属性
2
3
4
5
6
7
8
9
10
11
# 1.3 面向对象
JavaScript 虽然支持面向对象编程,但其语法和功能相对简单,缺乏一些高级特性(如接口、抽象类等)。
TypeScript 提供了完整的面向对象编程支持,包括类、接口、继承、泛型等。
# 1.4 模块化
JavaScript 的模块化支持(如 CommonJS 和 ES Modules)在大型项目中可能不够直观,容易导致代码组织混乱。
TypeScript 提供了更强大的模块化支持,可以更好地组织代码。
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
// main.ts
import { add } from "./math";
console.log(add(1, 2)); // 输出: 3
2
3
4
5
6
7
8
9
# 1.5 渐进式采用
如果直接切换到其他静态类型语言(如 Java、C#),可能需要完全重写现有代码。
TypeScript 是 JavaScript 的超集,现有的 JavaScript 代码可以直接在 TypeScript 中使用,逐步迁移到 TypeScript。
// 现有的 JavaScript 代码
function greet(name) {
return "Hello, " + name;
}
// 逐步添加类型
function greet(name: string): string {
return "Hello, " + name;
}
2
3
4
5
6
7
8
9
# 1.6 更早错误检测
JavaScript 的错误通常在运行时才能被发现,增加了调试和维护的难度。
TypeScript 在编译时进行类型检查,可以更早地发现潜在的错误。
let num: number = 42;
num = "Hello"; // 编译时报错:Type 'string' is not assignable to type 'number'.
2
# 1.7 总结一下
| 特性 | JavaScript | TypeScript |
|---|---|---|
| 类型系统 | 动态类型 | 静态类型 |
| 错误检测 | 运行时检测 | 编译时检测 |
| 代码提示 | 有限 | 强大 |
| 面向对象编程 | 支持,但功能有限 | 完整支持 |
| 模块化 | 支持,但不够直观 | 更强大的模块化支持 |
| 渐进式采用 | 无 | 支持 |
| 团队协作 | 缺乏类型信息,沟通成本高 | 类型系统作为文档,降低沟通成本 |
# 02.变量和常量
# 2.1 变量名
变量名遵循 JavaScript 的命名规则:
- 以字母、下划线(
_)或美元符号($)开头。 - 不能以数字开头。
- 区分大小写。
- 不能使用保留字(如
let、class等)。
# 2.2 变量声明
使用 let、const 或 var 声明变量:
let:块级作用域,可重新赋值。const:块级作用域,不可重新赋值。var:函数作用域,可重新赋值(不推荐使用)。
示例:
let age: number = 25;
const name: string = "Alice";
var isActive: boolean = true; // 不推荐
2
3
# 2.3 常量
const 用于声明一个常量,表示值不能被重新赋值。
# 03.数据类型
TypeScript 支持 JavaScript 的所有基本数据类型,并提供了额外的类型支持。
# 3.1 布尔类型
布尔类型 (boolean),表示 true 或 false。
let isDone: boolean = false;
# 3.2 数字类型
数字类型 (number),表示整数或浮点数,支持二进制、八进制、十进制和十六进制。
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
2
3
4
# 3.3 字符串类型
字符串类型 (string),表示文本数据,可以使用单引号、双引号或模板字符串。
let color: string = "blue";
color = `Color is ${color}`;
2
# 3.4 元组类型
元组类型 (Tuple),表示一个已知元素数量和类型的数组,各元素的类型可以不同。
由于成员的类型可以不一样,所以元组必须明确声明每个成员的类型。
let tuple: [string, number];
tuple = ["hello", 10]; // 正确
tuple = [10, "hello"]; // 错误
2
3
# 3.5 枚举类型
枚举类型 (enum),为一组数值赋予友好的名字。
enum Color { Red, Green, Blue }
let c: Color = Color.Green; // 1
2
# 3.6 任意类型
任意类型 (any),表示任意类型,关闭类型检查。
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;
2
3
# 3.7 空类型
空类型 (void),表示没有任何类型,通常用于函数返回值。
function warnUser(): void {
console.log("This is a warning message");
}
2
3
# 3.8 未知类型
表示 null 或 undefined 值。
let u: undefined = undefined;
let n: null = null;
2
unknown 类型,表示未知类型,比 any 更安全,需要类型检查后才能使用。
let value: unknown;
value = "hello";
if (typeof value === "string") {
console.log(value.toUpperCase());
}
2
3
4
5
# 3.9 never类型
表示永远不会发生的值,通常用于抛出异常或无限循环的函数。
function error(message: string): never {
throw new Error(message);
}
2
3
# 04.数组
# 4.1 基础数组类型
使用 [] 定义数组。表示一组相同类型的元素,有两种定义方式:
// TypeScript 会自动推断数组类型
// 数字数组
let scores1: number[] = [95, 87, 92, 100]; // 推断为 number[]
let scores2: Array<number> = [95, 87, 92, 100]; // 泛型语法
// 字符串数组
let names1: string[] = ["Alice", "Bob", "Charlie"]; // 推断为 string[]
let names2: Array<string> = ["Alice", "Bob", "Charlie"];
// 布尔数组
let flags: boolean[] = [true, false, true];
2
3
4
5
6
7
8
9
10
11
# 4.2 混合类型数组
数组元素可以是任意类型。
let mixed1: (number | string)[] = [1, "two", 3];
// 混合类型数组(不推荐,除非必要)
let mixed2: (string | number)[] = ["hello", 42, "world", 100];
2
3
# 4.3 只读数组
// 只读数组 - 创建后不能修改
const readOnlyNumbers: readonly number[] = [1, 2, 3];
// readOnlyNumbers.push(4); // 错误:push 不存在于类型 'readonly number[]'
// readOnlyNumbers[0] = 10; // 错误:索引签名只允许读取
// 其他只读数组声明方式
const ro1: ReadonlyArray<number> = [1, 2, 3];
const ro2: Readonly<number[]> = [1, 2, 3];
// 在函数参数中使用只读数组
function processNumbers(nums: readonly number[]): number {
return nums.reduce((sum, num) => sum + num, 0);
// nums.push(10); // 错误:只读数组
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 05.函数
# 5.1 函数声明
1.基本函数声明
function add(x: number, y: number): number {
return x + y;
}
2
3
2.函数表达式
const add = function(x: number, y: number): number {
return x + y;
};
2
3
3.箭头函数
const add = (x: number, y: number): number => x + y;
# 5.2 函数参数
1.参数类型
可以为函数的参数指定类型。
function greet(name: string): void {
console.log(`Hello, ${name}`);
}
2
3
2.可选参数
使用 ? 标记可选参数,可选参数必须位于必选参数之后。
function greet(name: string, age?: number): void {
if (age) {
console.log(`Hello, ${name}, you are ${age} years old`);
} else {
console.log(`Hello, ${name}`);
}
}
2
3
4
5
6
7
3.默认参数
为参数提供默认值。
function greet(name: string, age: number = 30): void {
console.log(`Hello, ${name}, you are ${age} years old`);
}
2
3
4.剩余参数
使用 ... 语法表示剩余参数,剩余参数必须是数组类型。
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3)); // 6
2
3
4
# 5.3 函数返回值
1.返回值类型
可以为函数指定返回值类型。
function add(x: number, y: number): number {
return x + y;
}
2
3
2.
void返回值
表示函数没有返回值。
function logMessage(message: string): void {
console.log(message);
}
2
3
3.
never返回值
表示函数永远不会返回(例如抛出异常或无限循环)。
function throwError(message: string): never {
throw new Error(message);
}
2
3
# 5.4 函数重载
TypeScript 支持函数重载,允许为同一个函数提供多个类型定义。
function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any): any {
return x + y;
}
console.log(add(1, 2)); // 3
console.log(add("Hello, ", "World")); // "Hello, World"
2
3
4
5
6
7
8
# 5.5 函数类型
1.函数类型定义
可以为函数定义类型。
type AddFunction = (x: number, y: number) => number;
const add: AddFunction = (x, y) => x + y;
2
2.函数作为参数
函数可以作为参数传递给其他函数。
function calculate(x: number, y: number, operation: (a: number, b: number) => number): number {
return operation(x, y);
}
const result = calculate(10, 5, (a, b) => a + b);
console.log(result); // 15
2
3
4
5
6
3.
this类型
可以为函数指定 this 的类型。
interface User {
name: string;
greet(this: User): void;
}
const user: User = {
name: "Alice",
greet() {
console.log(`Hello, ${this.name}`);
}
};
user.greet(); // "Hello, Alice"
2
3
4
5
6
7
8
9
10
11
12
13
# 5.6 泛型函数
使用泛型使函数适用于多种类型。
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("hello"); // 类型为 string
let output2 = identity<number>(42); // 类型为 number
2
3
4
5
6
# 5.7 异步函数
使用 async 和 await 处理异步操作。
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
fetchData().then(data => console.log(data));
2
3
4
5
6
7
# 5.8 函数类型推断
TypeScript 会根据上下文自动推断函数的参数和返回值类型。
const add = (x: number, y: number) => x + y; // 返回值类型推断为 number
# 5.9 函数类型守卫
通过条件语句缩小参数的类型范围。
function isString(value: any): value is string {
return typeof value === "string";
}
function printValue(value: string | number) {
if (isString(value)) {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
2
3
4
5
6
7
8
9
10
11