本篇由GPT辅助学习TypeScript而来的,仅为简单学习所创,若有疑惑还请去 TypeScript官网进一步了解
一、基础
1. 安装 TypeScript
在开始之前,你需要在你的电脑上安装 TypeScript 编译器。只需要几个步骤,就能拥有它。
步骤 1:安装 Node.js 和 npm 如果你还没有安装 Node.js,快去官网下载安装。Node.js 附带的 npm(包管理器)是我们接下来安装 TypeScript 的工具。
步骤 2:通过 npm 安装 TypeScript
npm install -g typescript
这样就将 TypeScript 安装到了你的机器上。-g
表示全局安装,可以在任何地方使用 tsc
命令。
步骤 3:检查安装是否成功
安装完后,输入以下命令检查 TypeScript 版本:
tsc --version
如果看到版本号,就表示安装成功!🎉
2. 创建你的第一个 TypeScript 文件
步骤 1:创建文件
用你喜欢的文本编辑器(如 VS Code、Sublime Text 等),创建一个文件,命名为 hello.ts
。这个 .ts
后缀标志着这是一个 TypeScript 文件。
步骤 2:编写代码
在 hello.ts
文件里,写一些简单的 TypeScript 代码:
let message: string = "Hello, TypeScript!";
console.log(message);
3. 编译 TypeScript 代码
在命令行中,切换到包含 hello.ts
的目录,然后运行以下命令将 TypeScript 代码编译成 JavaScript:
tsc hello.ts
运行后,你会看到同目录下生成了一个 hello.js
文件,内容类似这样:
var message = "Hello, TypeScript!";
console.log(message);
步骤 3:运行 JavaScript 代码
你可以使用 Node.js 来运行编译后的 JavaScript 文件:
node hello.js
你应该会看到控制台输出:
Hello, TypeScript!
4. 变量声明与类型注解
在 TypeScript 中,变量的类型不再是模糊不清的了。你可以在声明变量时指定它们的类型。这是 TypeScript 的超级武器之一!
基本类型
let age: number = 30; // 数字类型
let names: string = "TypeScript"; // 字符串类型
let isActive: boolean = true; // 布尔类型
数组
数组的类型可以用 []
来表示:
let numbers: number[] = [1, 2, 3]; // 数字数组
let fruits: string[] = ["apple", "banana", "cherry"]; // 字符串数组
或者使用 Array<type>
:
let numbers: Array<number> = [1, 2, 3];
元组
元组是一个固定长度和类型的数组:
let person: [string, number] = ["Alice", 25]; // 元组,第一个元素是字符串,第二个是数字
任意类型
有时候,你不确定变量的类型,可以使用 any
来表示:
let anything: any = "Hello"; // 类型可以是任何类型
anything = 42; // 现在是数字了
anything = true; // 现在是布尔类型了
字面量
用于约束变量的值为特定字符串、数字或布尔值的类型。
let direction: "up" | "down" = "up"; // 只能是 "up" 或 "down"
direction = "down"; // OK
direction = "left"; // 错误:不能赋值 "left"
枚举类型(Enums)
枚举用于定义一组具名的常数,通常用于表示一组有限的状态或选项。
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
let move: Direction = Direction.Up; // 使用枚举
未知类型
如果你想声明一个不确定的变量类型,但又想要一些检查,可以使用 unknown
,它比 any
更安全:
let value: unknown = "hello";
value = 42; // 也可以是数字
5. 函数与类型注解
函数也可以定义参数类型和返回类型。这就是 TypeScript 的类型检查功能,能提前警告你代码中的潜在问题。
函数声明
function greet(name: string): string {
return `Hello, ${name}!`;
}
let greeting = greet("TypeScript");
console.log(greeting); // 输出 "Hello, TypeScript!"
可选参数
你也可以设置参数为可选的,只需要在参数后加一个问号:
function greet(name: string, age?: number): string {
if (age) {
return `Hello, ${name}! ${age} `;
}
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // 输出 "Hello, Alice!"
console.log(greet("Bob", 18)); // 输出 "Hello, Bob! 18"
6. 总结
你现在已经有了一个 TypeScript 文件,成功安装了 TypeScript 编译器,并了解了如何声明变量、定义类型和编写简单的函数。是不是感觉有点厉害了?😎
接下来,你可以探索更多高级功能,如 类、接口、泛型、模块 等等,但今天我们就先从基础开始,让你顺利地飞起来!🚀
二、进阶
让我们继续扩展 TypeScript 的神奇世界,一口气包括更多常用类型、类型别名、函数类型、对象类型等,也涵盖一些高级类型,让你的 TypeScript 技能更上一层楼。准备好了吗?我们开始!🚀
常用类型
1. 类型别名
类型别名(Type Aliases)用来给一个类型取个别名,可以让你的代码更简洁易懂。
type StringOrNumber = string | number; // String 或 Number 类型
let data: StringOrNumber = "hello"; // 可以是 string 或 number
data = 42; // 也可以是数字
2. 对象类型
对象类型(Object Types)是用来描述对象的结构,确保对象中的每个属性都有合适的类型。
type Person = {
name: string;
age: number;
};
const person: Person = {
name: "Alice",
age: 30,
};
let person:{name: string;age: number;} ={
name: "Alice",
age: 30,
}
3. 类型断言
类型断言(Type Assertions)告诉 TypeScript 编译器,开发者“知道”某个变量的确切类型,通常用于从更宽泛的类型转换为更精确的类型。
let message: any = "Hello, TypeScript!";
let strLength: number = (message as string).length; // 类型断言为 string
4.typeof
操作符
typeof
用于获取变量的类型,通常用于与 类型保护 和 类型推论 配合使用。
let name = "Alice";
let nameType: typeof name = "Bob"; // 类型为 string
高级类型
1. 类
类(Class)是面向对象编程的重要组成部分,TypeScript 中的类提供了更多的功能和类型检查。
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog("Buddy");
dog.speak(); // 输出 "Buddy barks."
在 TypeScript 中,两个类型如果结构相同,它们是兼容的。
interface Animal {
name: string;
}
class Dog {
name: string;
constructor(name: string) {
this.name = name;
}
}
let dog: Dog = new Dog("Buddy");
let animal: Animal = dog; // 兼容,因为 Dog 类符合 Animal 接口的结构
2. 交叉类型
交叉类型(Intersection Types)是将多个类型合并为一个类型,合并后的类型包含了所有类型的成员。
type Person = {
name: string;
age: number;
};
type Employee = {
jobTitle: string;
};
type EmployeePerson = Person & Employee; // 交叉类型
const employee: EmployeePerson = {
name: "Alice",
age: 30,
jobTitle: "Developer",
};
3. 泛型与 keyof
泛型(Generics)允许你定义可以接受任意类型的函数、类、接口等,确保类型安全。
function identity<T>(arg: T): T {
return arg;
}
let result = identity<string>("Hello!"); // 类型是 string
let numResult = identity<number>(42); // 类型是 number
keyof
用来提取某个对象的所有键,并形成一个类型。
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
4. 索引签名类型与 索引查询类型
索引签名类型(Index Signature Types) 允许你定义可以动态访问的对象类型。
interface Dictionary {
[key: string]: string;
}
const dict: Dictionary = {
hello: "world",
foo: "bar",
};
索引查询类型(Index Access Types) 允许你查询对象类型的某个属性的类型。
type NameType = Person["name"]; // 类型是 string
5 映射类型
映射类型(Mapped Types)允许你根据某个类型创建一个新类型,常用于批量修改对象的属性。
type ReadOnly<T> = {
readonly [K in keyof T]: T[K];
};
interface Person {
name: string;
age: number;
}
const person: ReadOnly<Person> = { name: "Alice", age: 30 };
// person.name = "Bob"; // 错误,属性是只读的
也可以结合 in
操作符来创建新的类型。
type PartialPerson = {
[K in keyof Person]?: Person[K]; // 将 Person 中的所有属性变为可选
};
6.总结
现在你已经有了 TypeScript 的常用类型、类型别名、函数类型、对象类型等的全面了解,还可以更深入地理解高级类型如类、交叉类型、泛型、映射类型等。通过这些强大的特性,TypeScript 能够帮助你编写更加灵活、安全且可维护的代码。是不是已经迫不及待要开始动手写更复杂的 TypeScript 项目了呢?🎉
三、文件类型
TypeScript 是个聪明的小家伙,它通过 .ts
和 .d.ts
两种文件类型让我们编写代码时更加得心应手!让我们一个个捋顺清楚,看看它们之间的“微妙”区别吧!🚀
1. .ts
文件 — TypeScript 的“主战场”
.ts
文件就是 TypeScript 的本体,里面包含了你写的所有实现代码。你写的函数、类、变量,甚至所有的类型注解都在这里。可以说它是 TypeScript 的灵魂,是我们“战斗”的地方!💥
用途:编写程序代码的地方。
- 你最常用的文件类型——这里写代码!
- 可以写任何可执行的 TypeScript 代码——函数、类、对象、你想要的一切都在这里!
- 编译成 JavaScript,跑在浏览器或 Node.js 环境中。🎯
示例:
// hello.ts — 你开始写的第一行 TypeScript 代码!🎉
function greet(name: string): string {
return `Hello, ${name}!`; // 就这么简单,带着热情!
}
console.log(greet("Alice")); // 输出: Hello, Alice!
小贴士:
- 运行
tsc hello.ts
之后,你会发现编译器生成了hello.js
文件,这个文件就是最终执行的 JavaScript 代码。 - 你可以通过
node hello.js
来运行它,看看效果如何!🌟
2. .d.ts
文件 — 类型声明的超级英雄
.d.ts
文件就像是 TypeScript 的“隐形助手”——它不会参与执行,但却能让你的代码在幕后更有条理。它专门用来给你的 JavaScript 提供类型信息,帮助 TypeScript 理解“这个东西应该是什么类型”!😎
用途:为 JS 提供类型信息
- 为外部库(那些没有内置 TypeScript 类型的 JavaScript 库)提供类型定义。👑
- 你可以用它来描述 JavaScript 代码的结构,确保 TypeScript 编译器能够正确识别并提供类型检查。📚
- 不包含实际实现代码,只是类型的“地图”。✨
示例:
假设你在用某个 JavaScript 库,里面有个 greet
函数,但它没有 TypeScript 类型信息。怎么办?没关系,来个 .d.ts
文件吧!
// greet.d.ts — 类型定义开始!
declare function greet(name: string): string; // 只定义函数签名,没有实现!
这个 .d.ts
文件告诉 TypeScript:“嘿,greet
函数是存在的,而且它接受一个字符串参数并返回一个字符串!”这样 TypeScript 就能通过这个类型信息来为你提供智能提示和类型检查了!✨
3..ts
与 .d.ts
文件的关键区别
特性 | .ts 文件 | .d.ts 文件 |
---|---|---|
目的 | 编写 TypeScript 可执行代码,编译成 JavaScript 运行 | 提供类型声明,告诉 TypeScript 其他代码的结构和类型 |
内容 | 包含实现代码(函数、类、逻辑等) | 仅包含类型定义,没有实现代码 |
编译 | 编译成 .js 文件 | 不编译成 JavaScript 文件,仅用于类型检查 |
场景 | 编写程序的核心逻辑、功能等 | 为第三方库提供类型定义,或为 JavaScript 代码添加类型定义 |
4.如何使用 .d.ts
文件
- 为第三方库添加类型定义
你在使用一个没有 TypeScript 类型定义的 JavaScript 库时,怎么办?别担心!只需要通过 @types
包来引入它们的类型声明文件!🎉
举个例子,如果你在用 Lodash(一个 JavaScript 的工具库),并且想用它的类型定义:
npm install @types/lodash
这个命令会安装 Lodash 的类型声明文件,TypeScript 就会知道 Lodash 是怎样工作的,让你享受到类型检查和代码补全的好处!👏
手动为 JavaScript 写声明文件
如果你自己有一些 JavaScript 文件,也可以自己写 .d.ts
文件来为它们添加类型信息。比如你写了一个 utils.js
文件,你可以写一个 utils.d.ts
来描述它的类型:
// utils.d.ts
declare function formatDate(date: Date): string; // 格式化日期的函数
declare function sum(a: number, b: number): number; // 加法函数
MyButton: typeof MyButton;
这样 TypeScript 就知道了 formatDate
和 sum
函数的类型,不用再怕类型错误了!💪
5.总结:TS 里的 .ts
和 .d.ts
文件
.ts
文件:你的主战场,里面的代码会被编译为 JavaScript 并运行。它包含了你所有的功能实现,类型注解,甚至你的勇气!🚀.d.ts
文件:类型声明的超级英雄,它让 TypeScript 知道其他 JavaScript 文件的类型结构,确保你的代码在没有实际实现的情况下也能进行类型检查。🦸♂️
这两种文件的结合,让 TypeScript 能够发挥最大的优势,既保证代码的灵活性,又确保类型安全。记住,.ts
文件用来写逻辑,.d.ts
文件用来给外部代码“写传单”!😏