引言
大家好,我是GISer Liu😁,一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的TypeScript学习总结文档。希望通过我的知识点总结,能够帮助你更好地学习TypeScript。💕💕😊
一、介绍:
1.什么是 TypeScript?
TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集,意味着任何有效的 JavaScript 代码也是有效的 TypeScript 代码。TypeScript 在 JavaScript 的基础上增加了静态类型检查、类、接口、模块等特性,使得开发者可以在编写代码时更早地发现错误,提高代码的可维护性和可读性。
应用场景:
- 大型项目开发
- 团队协作
- 需要强类型检查的场景
代码示例:
// 定义一个接口来描述用户对象的结构
interface User {
id: number;
name: string;
email: string;
isAdmin: boolean;
}
// 定义一个类来表示用户
class UserService {
private users: User[] = [];
// 添加用户
addUser(user: User): void {
this.users.push(user);
}
// 获取所有用户
getUsers(): User[] {
return this.users;
}
// 根据ID查找用户
findUserById(id: number): User | undefined {
return this.users.find(user => user.id === id);
}
// 删除用户
deleteUser(id: number): void {
this.users = this.users.filter(user => user.id !== id);
}
}
// 创建一个 UserService 实例
const userService = new UserService();
// 添加一些用户
userService.addUser({ id: 1, name: "Alice", email: "alice@example.com", isAdmin: true });
userService.addUser({ id: 2, name: "Bob", email: "bob@example.com", isAdmin: false });
// 获取所有用户并打印
console.log("All Users:", userService.getUsers());
// 查找并打印特定用户
const user = userService.findUserById(1);
console.log("Found User:", user);
// 删除用户并打印剩余用户
userService.deleteUser(1);
console.log("Remaining Users:", userService.getUsers());
2.TypeScript 与 JavaScript 的区别
1. 类型系统
JavaScript:
- 动态类型:变量类型在运行时确定。
- 无显式类型声明。
TypeScript:
- 静态类型:变量类型在编译时确定。
- 显式类型声明:如
number
、string
、boolean
等。 - 类型推断:支持类型推断,但鼓励显式声明。
示例:
// JavaScript
let age = 30; // 类型推断为 number
age = "thirty"; // 类型可以改变
// TypeScript
let age: number = 30; // 显式声明为 number 类型
// age = "thirty"; // 错误:不能将类型 "string" 分配给类型 "number"
2. 语法差异
JavaScript:
- 函数声明:使用
function
关键字。 - 类:ES6 引入,基于原型继承。
- 模块:ES6 引入,使用
import
和export
关键字。
TypeScript:
- 函数声明:支持显式声明参数和返回值类型。
- 类:更强大的类支持,包括访问修饰符、只读属性、抽象类和接口。
- 模块:支持 ES6 模块系统,提供更强大的模块声明和命名空间功能。
示例:
// JavaScript
function add(a, b) {
return a + b;
}
// TypeScript,规定输入输出的格式
function add(a: number, b: number): number {
return a + b;
}
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
greet(): string {
return `Hello, my name is ${this.name}`;
}
}
**<font style="color:rgb(60, 60, 67);background-color:rgb(247, 247, 247);">public</font>**
: 默认访问修饰符,表示成员可以在类的内部和外部访问。**<font style="color:rgb(60, 60, 67);background-color:rgb(247, 247, 247);">private</font>**
: 表示成员只能在类的内部访问,外部无法访问。**<font style="color:rgb(60, 60, 67);background-color:rgb(247, 247, 247);">protected</font>**
: 表示成员可以在类的内部和子类中访问,外部无法访问。**<font style="color:rgb(60, 60, 67);background-color:rgb(247, 247, 247);">constructor</font>**
是类的构造函数,用于初始化对象的属性。
3. 编译过程
JavaScript:
- 解释执行:代码由浏览器或 Node.js 解释执行。
TypeScript:
- 编译执行:代码需通过
tsc
编译成 JavaScript 代码。 - 类型检查:编译时进行类型检查,确保类型安全。
示例:
// TypeScript 代码
let message: string = "Hello, TypeScript!";
console.log(message);
// 编译后的 JavaScript 代码
let message = "Hello, TypeScript!";
console.log(message);
4. 应用场景
JavaScript:
- 前端开发:构建动态网页和交互式用户界面。
- 后端开发:Node.js 使用 JavaScript 进行后端开发。
TypeScript:
- 大型项目:适用于需要强类型检查和代码可维护性的项目。
- 团队协作:静态类型系统有助于团队协作,减少代码冲突和错误。
- 现代前端框架:与 Angular、React、Vue.js 集成良好。
示例:
// JavaScript 前端代码
document.getElementById("demo").innerHTML = "Hello, JavaScript!";
// TypeScript 前端代码
let element: HTMLElement = document.getElementById("demo");
element.innerHTML = "Hello, TypeScript!";
5. 工具支持
JavaScript:
- 开发工具:Chrome DevTools、Visual Studio Code 等。
- 调试:直接在浏览器或 Node.js 中调试。
TypeScript:
- 开发工具:与 Visual Studio Code 集成良好,提供强大的代码补全、重构和调试功能。
- 调试:需编译成 JavaScript 后调试,但 IDE 提供丰富调试支持。
示例:
// TypeScript 代码
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("TypeScript"));
6. 错误检查
JavaScript:
- 运行时错误:错误通常在代码执行时才会被发现。
TypeScript:
- 编译时错误:在编译时进行类型检查,减少运行时错误。
示例:
// JavaScript
function add(a, b) {
return a + b;
}
console.log(add(1, "2")); // 输出: "12",类型错误未被发现
// TypeScript
function add(a: number, b: number): number {
return a + b;
}
// console.log(add(1, "2")); // 错误:不能将类型 "string" 分配给类型 "number"
7. 模块化与代码组织
JavaScript:
- 模块系统:ES6 引入,但模块化支持较弱。
- 代码组织:依赖文件和模块,缺乏强类型支持。
TypeScript:
- 模块系统:支持 ES6 模块系统,提供更强大的模块声明和命名空间功能。
- 代码组织:类型系统和模块化支持使得代码组织更清晰和易于维护。
示例:
// JavaScript 模块
export function greet(name) {
return `Hello, ${name}!`;
}
// TypeScript 模块
export function greet(name: string): string {
return `Hello, ${name}!`;
}
通过这些简化的对比,可以一目了然地了解 TypeScript 与 JavaScript 的主要区别。TypeScript 通过引入静态类型检查和其他高级特性,显著提高了代码的健壮性和可维护性,特别适用于大型项目和团队协作开发。
3.为什么选择 TypeScript?
选择 TypeScript 的原因有很多,主要包括以下几点:
- 静态类型检查: TypeScript 提供了静态类型检查,可以在编写代码时发现潜在的错误,减少运行时错误。
- 更好的代码可维护性: 类型系统使得代码更易于理解和维护,特别是在大型项目中。
- 现代语言特性: TypeScript 支持 ES6+ 的许多新特性,如类、模块、箭头函数等。
- 强大的工具支持: TypeScript 与现代 IDE(如 Visual Studio Code)集成良好,提供了强大的代码补全、重构和调试功能。
应用场景:
- 大型前端项目
- 需要强类型检查的后端项目
- 团队协作开发
代码示例:
// TypeScript 代码
function add(a: number, b: number): number {
return a + b;
}
console.log(add(1, 2)); // 输出: 3
4.TypeScript 的安装与环境配置
要开始使用 TypeScript,首先需要在开发环境中安装 TypeScript 编译器(tsc
)。TypeScript 编译器可以将 TypeScript 代码编译成 JavaScript 代码。
安装步骤:
- 安装 Node.js: TypeScript 依赖于 Node.js 环境,因此首先需要安装 Node.js。可以从 Node.js 官网 下载并安装。
- 安装 TypeScript: 使用 Node.js 的包管理工具
npm
安装 TypeScript。
npm install -g typescript
- 验证安装: 安装完成后,可以通过以下命令验证 TypeScript 是否安装成功。
tsc --version
环境配置:
- 创建 TypeScript 项目: 创建一个新的项目文件夹,并在其中初始化
npm
项目。
mkdir test
cd test
npm init -y
- 配置 TypeScript: 在项目根目录下创建一个
tsconfig.json
文件,用于配置 TypeScript 编译选项。
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
- 编写 TypeScript 代码: 在
src
目录下创建 TypeScript 文件(如index.ts
),并编写代码。
// src/index.ts
let message: string = "Hello, TypeScript!";
console.log(message);
- 编译 TypeScript 代码: 使用
tsc
命令编译 TypeScript 代码。
tsc
编译后的 JavaScript 代码将生成在 dist
目录下。
- 运行 JavaScript 代码: 使用 Node.js 运行编译后的 JavaScript 代码。
node dist/index.js
tsconfig.json
文件配置了 TypeScript 编译器的选项,如目标 ECMAScript 版本、模块系统、输出目录等。tsc
命令将 TypeScript 代码编译成 JavaScript 代码,并输出到dist
目录。node
命令用于运行编译后的 JavaScript 代码。
二 、TypeScript 基础语法
1. 变量声明与数据类型
①基本数据类型
在 TypeScript 中,数据类型是确保代码健壮性和可维护性的关键。了解这些基本数据类型及其应用场景,可以帮助开发者在编写代码时避免许多常见的错误。
■ number
介绍:
number
类型用于表示整数和浮点数。与 JavaScript 不同,TypeScript 中没有 int
和 float
的区分,所有数字都是 number
类型。
应用场景:
- 计算、计数、索引等数值操作。
代码示例:
let age: number = 25;
let price: number = 19.99;
console.log(age); // 输出: 25
console.log(price); // 输出: 19.99
解读:
age
是一个整数,price
是一个浮点数。- TypeScript 会自动推断
age
和price
的类型为number
。
■ string
介绍:
string
类型用于表示文本数据。可以使用单引号(')、双引号(")或反引号(`)来定义字符串。
应用场景:
- 用户输入、文本处理、日志记录等。
代码示例:
let greeting: string = "Hello, TypeScript!";
let message: string = `Welcome to ${greeting}`;
console.log(greeting); // 输出: Hello, TypeScript!
console.log(message); // 输出: Welcome to Hello, TypeScript!
解读:
greeting
是一个简单的字符串。message
使用了模板字符串,可以在字符串中嵌入表达式。
■ boolean
介绍:
boolean
类型表示逻辑值,只有两个可能的值:true
和 false
。
应用场景:
- 条件判断、开关状态、逻辑运算等。
代码示例:
let isStudent: boolean = true;
let isLoggedIn: boolean = false;
console.log(isStudent); // 输出: true
console.log(isLoggedIn); // 输出: false
解读:
isStudent
和isLoggedIn
分别表示两个布尔值。- 布尔值常用于条件语句中,如
if
语句。
■ enum
介绍:
enum
类型用于定义一组命名的常量。它可以帮助你更好地组织代码,并提高代码的可读性。
应用场景:
- 状态码、选项列表、配置项等。
代码示例:
enum Color {
Red,
Green,
Blue
}
let selectedColor: Color = Color.Blue;
console.log(selectedColor); // 输出: 2
解读:
Color
枚举定义了三个颜色选项。selectedColor
被赋值为Color.Blue
,其值为2
。
■ void
介绍:
void
类型用于表示没有返回值的函数。它通常用于函数的返回类型声明。
应用场景:
- 不返回任何值的函数。
代码示例:
function logMessage(): void {
console.log("This is a log message.");
}
logMessage(); // 输出: This is a log message.
logMessage
函数没有返回值,因此其返回类型为void
。
■ null
和 undefined
概念:
null
和 undefined
是两种特殊的数据类型,分别表示空值和未定义的值。
应用场景:
- 初始化变量、处理未定义的值、空值检查等。
代码示例:
let emptyValue: null = null;
let undefinedValue: undefined = undefined;
console.log(emptyValue); // 输出: null
console.log(undefinedValue); // 输出: undefined
emptyValue
被显式赋值为null
。
undefinedValue
被显式赋值为undefined
。
■ any
和 never
概念:
any
类型允许变量存储任何类型的值,通常用于与动态内容交互或绕过类型检查。never
类型表示永远不会发生的值,通常用于函数的返回类型,表示函数永远不会返回。
应用场景:
any
:处理动态内容、与第三方库交互等。never
:处理异常、无限循环等。
代码示例:
let dynamicValue: any = "This can be anything";
dynamicValue = 42;
function throwError(message: string): never {
throw new Error(message);
}
console.log(dynamicValue); // 输出: 42
throwError("An error occurred"); // 抛出错误
dynamicValue
可以存储任何类型的值。
throwError
函数永远不会返回,因此其返回类型为never
。
②变量声明方式
在 TypeScript 中,变量声明有多种方式,每种方式都有其特定的应用场景和优缺点。
■ 显式类型声明
显式类型声明是指在声明变量时明确指定其类型。这种方式可以提高代码的可读性和可维护性。
应用场景:
- 需要明确指定变量类型的场景。
代码示例:
let name: string = "Alice";
let age: number = 30;
console.log(name); // 输出: Alice
console.log(age); // 输出: 30
name
被显式声明为string
类型。
age
被显式声明为number
类型。
■ 隐式类型推断
介绍:
隐式类型推断是指 TypeScript 根据变量的初始值自动推断其类型。这种方式可以减少代码量,但可能会降低代码的可读性。
应用场景:
- 变量初始值明确且类型简单的场景。
代码示例:
let name = "Alice"; // TypeScript 推断 name 为 string 类型
let age = 30; // TypeScript 推断 age 为 number 类型
console.log(name); // 输出: Alice
console.log(age); // 输出: 30
解读:
name
和age
的类型由 TypeScript 自动推断。
■ 未初始化的变量
介绍:
未初始化的变量是指在声明变量时未指定初始值。这种情况下,变量的类型默认为 any
,除非显式指定类型。
应用场景:
- 变量初始值不确定或需要在后续代码中赋值的场景。
代码示例:
let name: string; // 显式声明类型
let age; // 未初始化,类型默认为 any
name = "Alice";
age = 30;
console.log(name); // 输出: Alice
console.log(age); // 输出: 30
解读:
name
被显式声明为string
类型。age
未初始化,类型默认为any
。
③变量作用域
变量作用域决定了变量在代码中的可见性和生命周期。了解变量作用域可以帮助你更好地组织代码,避免变量冲突和意外行为。
■ 全局作用域
全局作用域是指变量在程序的任何地方都可以访问。全局变量通常定义在程序的最外层。
应用场景:
- 需要在多个模块或函数中共享的变量。
代码示例:
let globalVar = "I am global";
function printGlobal() {
console.log(globalVar); // 输出: I am global
}
printGlobal();
globalVar
是一个全局变量,可以在任何地方访问。
■ 类作用域(实例变量与静态变量)
类作用域是指变量在类内部定义,可以通过类的实例或类名访问。实例变量属于类的实例,静态变量属于类本身。
应用场景:
- 需要在类内部共享的变量。
代码示例:
class MyClass {
instanceVar = "I am an instance variable";
static staticVar = "I am a static variable";
printInstanceVar() {
console.log(this.instanceVar);
}
static printStaticVar() {
console.log(MyClass.staticVar);
}
}
let obj = new MyClass();
obj.printInstanceVar(); // 输出: I am an instance variable
MyClass.printStaticVar(); // 输出: I am a static variable
instanceVar
是一个实例变量,通过类的实例访问。
staticVar
是一个静态变量,通过类名访问。
■ 局部作用域
局部作用域是指变量在函数或代码块内部定义,只能在定义它的函数或代码块内部访问。
应用场景:
- 需要限制变量可见性的场景。
代码示例:
function printLocalVar() {
let localVar = "I am a local variable";
console.log(localVar); // 输出: I am a local variable
}
printLocalVar();
// console.log(localVar); // 错误: localVar 在此处不可访问
localVar
是一个局部变量,只能在printLocalVar
函数内部访问。
2.TypeScript中的运算符
运算符是用于执行特定操作的符号或关键字。TypeScript 支持多种运算符,包括算术运算符、关系运算符、逻辑运算符、赋值运算符、三元运算符、字符串运算符和类型运算符。
① 算术运算符
算术运算符用于执行基本的数学运算。
示例:
var num1: number = 10;
var num2: number = 2;
var res: number = 0;
res = num1 + num2;
console.log("加: " + res); // 输出: 12
res = num1 - num2;
console.log("减: " + res); // 输出: 8
res = num1 * num2;
console.log("乘: " + res); // 输出: 20
res = num1 / num2;
console.log("除: " + res); // 输出: 5
res = num1 % num2;
console.log("余数: " + res); // 输出: 0
num1++;
console.log("num1 自增运算: " + num1); // 输出: 11
num2--;
console.log("num2 自减运算: " + num2); // 输出: 1
其中:
+
用于加法运算。-
用于减法运算。*
用于乘法运算。/
用于除法运算。%
用于取模运算,返回除法的余数。++
用于自增运算,将变量的值加 1。--
用于自减运算,将变量的值减 1。
② 关系运算符
关系运算符用于比较两个值,并返回一个布尔值(true
或 false
)。
示例:
var num1: number = 5;
var num2: number = 9;
console.log("num1 的值为: " + num1); // 输出: 5
console.log("num2 的值为: " + num2); // 输出: 9
var res: boolean = num1 > num2;
console.log("num1 大于 num2: " + res); // 输出: false
res = num1 < num2;
console.log("num1 小于 num2: " + res); // 输出: true
res = num1 >= num2;
console.log("num1 大于或等于 num2: " + res); // 输出: false
res = num1 <= num2;
console.log("num1 小于或等于 num2: " + res); // 输出: true
res = num1 == num2;
console.log("num1 等于 num2: " + res); // 输出: false
res = num1 != num2;
console.log("num1 不等于 num2: " + res); // 输出: true
>
用于判断左边的值是否大于右边的值。<
用于判断左边的值是否小于右边的值。>=
用于判断左边的值是否大于或等于右边的值。<=
用于判断左边的值是否小于或等于右边的值。==
用于判断两个值是否相等。!=
用于判断两个值是否不相等。
③ 逻辑运算符
逻辑运算符用于组合或反转布尔值,无非也就是与或非那一套;
示例:
var avg: number = 20;
var percentage: number = 90;
console.log("avg 值为: " + avg + ", percentage 值为: " + percentage); // 输出: 20, 90
var res: boolean = ((avg > 50) && (percentage > 80));
console.log("(avg > 50) && (percentage > 80): " + res); // 输出: false
var res: boolean = ((avg > 50) || (percentage > 80));
console.log("(avg > 50) || (percentage > 80): " + res); // 输出: true
var res: boolean = !((avg > 50) && (percentage > 80));
console.log("!((avg > 50) && (percentage > 80)): " + res); // 输出: true
解读:
&&
是逻辑与运算符,只有当两个表达式都为true
时,结果才为true
。||
是逻辑或运算符,只要有一个表达式为true
,结果就为true
。!
是逻辑非运算符,用于反转布尔值,如果表达式为true
,则结果为false
,反之亦然。
④ 赋值运算符
赋值运算符用于将值赋给变量。
示例:
var a: number = 12;
var b: number = 10;
a = b;
console.log("a = b: " + a); // 输出: 10
a += b;
console.log("a += b: " + a); // 输出: 20
a -= b;
console.log("a -= b: " + a); // 输出: 10
a *= b;
console.log("a *= b: " + a); // 输出: 100
a /= b;
console.log("a /= b: " + a); // 输出: 10
a %= b;
console.log("a %= b: " + a); // 输出: 0
解读:
=
用于将右边的值赋给左边的变量。+=
先进行加法运算,然后将结果赋给左边的变量。-=
先进行减法运算,然后将结果赋给左边的变量。*=
先进行乘法运算,然后将结果赋给左边的变量。/=
先进行除法运算,然后将结果赋给左边的变量。%=
先进行取模运算,然后将结果赋给左边的变量。
⑤ 三元运算符
三元运算符是一种简洁的条件表达式,用于根据条件选择不同的值。可以将其看作是一种条件语句,在小范围赋值的情况下很好用,;例如设置默认值;
示例:
var num: number = -2;
var result = num > 0 ? "大于 0" : "小于 0,或等于 0";
console.log(result); // 输出: 小于 0,或等于 0
解读:
- 三元运算符的语法是
condition ? expr1 : expr2
。 - 如果
condition
为true
,则返回expr1
,否则返回expr2
。
⑥ 字符串运算符
字符串运算符用于连接字符串。
示例:
var msg: string = "hello " + "world";
console.log(msg); // 输出: hello world
解读:
+
运算符用于连接两个字符串。
⑦ 类型运算符
类型运算符用于获取变量的类型。
示例:
var num = 12;
console.log(typeof num); // 输出: number
typeof
运算符返回操作数的数据类型。
三、总结
在本文中,我们深入探讨了 TypeScript 的基础知识,包括其定义、与 JavaScript 的区别等信息;详细说明了TypeScript如何声明变量和使用各种数据类型,如 number
、string
、boolean
等。此外,我们还了解了 TypeScript 中的运算符,包括算术运算符、关系运算符、逻辑运算符、三元运算符等使用案例;
通过这些内容,我们初步掌握了 TypeScript 的核心概念和基本语法,为后续的学习打下了坚实的基础。
在下一篇文章中,作者将深入探讨 TypeScript 的控制语句,包括条件语句(如 if
、else
、switch
)和循环语句(如 for
、while
、do...while
)。这些控制语句是编程中的基础,掌握它们将帮助我们编写更加复杂和功能强大的程序。
敬请期待!🚀
相关链接
- 项目地址:TypeScript-CookBook
- 相关文档:专栏地址
- 作者主页:GISer Liu-CSDN博客
如果觉得我的文章对您有帮助,三连+关注便是对我创作的最大鼓励!或者一个star🌟也可以😂.