前言
首先 TypeScript 是 JavaScript 的超集。在写图书管理系统的项目时,大部分使用的是 TypeScript 语言。毕竟是从零开始学的 TypeScript ,甚至 JavaScript 还没学明白就直接跑来写 TypeScript 了。在写的过程中经常会有许多的疑惑,决定写这篇文章记录下来。
type 关键字
首先看到下面这玩意就挺蒙的,到后面才知道这个 type 居然是个函数…
虽然知道箭头函数这个东西,但还是蒙的…
1
| type RequestHandler = (req: IncomingMessage, res: ServerResponse) => void;
|
type 基本语法和用法
这玩意基础语法非常简单:
最基本的用法就如下,给基本类型取个别的名称:
1 2 3 4 5 6 7
| type ID = string; let userId: ID = "abc123";
type Status = "active" | "inactive" | "pending"; let currentStatus: Status = "active";
|
然后是定义联合类型,表示一个值可以是几种类型之一:
1 2 3 4 5 6
| type StringOrNumber = string | number;
let value: StringOrNumber; value = "hello"; value = 123;
|
既然有联合肯定有交叉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| type Person = { name: string; };
type Employee = { employeeId: string; };
type Worker = Person & Employee;
let myWorker: Worker = { name: "Bob", employeeId: "E001" };
|
定义数组和元组
1 2 3 4 5 6 7
| type NumberArray = number[]; let scores: NumberArray = [90, 85, 100];
type UserInfoTuple = [string, number]; let user: UserInfoTuple = ["Charlie", 30];
|
type 定义对象
这是 type 最常见的用法之一,用来描述一个对象里面有写啥参数:
1 2 3 4 5 6 7 8 9 10 11 12
| type User = { name: string; age: number; email?: string; readonly id: number; };
let user1: User = { id: 1, name: "Alice", age: 25, };
|
type 定义函数类型
这个就是最初的疑惑了,type 可以用来定义函数的参数和返回值类型:
1 2 3 4 5 6
| type GreetFunction = (name: string) => string;
const greet: GreetFunction = (name) => { return `Hello, ${name}`; };
|
type 定义泛型类型
type 可以定义带有泛型参数的类型,增加类型的复用性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| type ApiResponse<T> = { code: number; message: string; data: T; };
let stringRes: ApiResponse<string> = { code: 200, message: "success", data: "some string data" };
let userRes: ApiResponse<User> = { code: 200, message: "success", data: { name: "Dave", age: 40, id: 2 } };
|
之前就有见到过 这个东西,完全看不懂,这里也是我第一次接触到泛型,写这段话时在解决如何消灭 any 这个类型的问题,好像就和泛型有关。
type 与 interface 的区别
不知道 (即答) (o′ω`o)ノ,写这段话时甚至 interface 都没用过呢 <(▰˘◡˘▰)>
但是查到的资料 (问AI) 上是这么写的,记录一下,以后用 interface 时来看一眼
AI 说: 在定义对象类型时,type 和 interface 非常相似,很多时候可以互换,但它们有核心区别
| 特性 |
type |
interface |
| 核心定位 |
类型别名(给任何类型起名字) |
接口(描述对象的形状) |
| 对象扩展 |
使用交叉类型& |
使用extends关键字 |
| 声明合并 |
不支持(同名type会报错) |
支持(同名interface会自动合并,在扩展第三方库很有用) |
| 联合/交叉类型 |
支持(type A = B 或 C) |
不支持(不能写 interface A extends B 或 C) |
| 基本类型别名 |
支持(type ID = String) |
不支持 |
| 元组/函数 |
更简洁自然 |
也能定义,但语法稍显怪异 |
Promise 对象
我了个豆哪里蹦出来的 reslve 和 reject ?
好了这下知道了,这函数返回一个 promise ,而 JS 引擎自动提供的两个参数:resolve 和 reject 这俩回调函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function received(req: IncomingMessage): Promise<any> { return new Promise((resolve, reject) => { let buffer = Buffer.alloc(0); req.on("data", (chunk) => { buffer = Buffer.concat([buffer, chunk]); }); req.on("end", () => { try { const body = buffer.toString(); resolve(JSON.parse(body)); } catch (e) { reject(e); } }); req.on("error", reject); }); }
|
async 异步编程
这里放上一段异步函数与同步函数的对比:
同步函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import time
def fetch_data(id): print(f"开始获取数据 {id}...") time.sleep(2) print(f"数据 {id} 获取完毕") return f"Result {id}"
def main(): start = time.time() result1 = fetch_data(1) result2 = fetch_data(2) print(f"总耗时: {time.time() - start:.2f} 秒")
main()
|
异步函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const sleep = (ms: number) => new Promise<void>(resolve => setTimeout(resolve, ms));
async function fetchData (id: number): Promise<string> { console.log(`正在获取数据${id}`); await sleep(2000); console.log(`获取数据${id}完毕`); return `Result ${id}`; }
async function main() { const start = Date.now(); const results = await Promise.all([ fetchData(1), fetchData(2) ]); console.log(results); console.log(`总耗时: ${((Date.now() - start) / 1000).toFixed(2)} 秒`); }
main();
|
呃,JavaScript 是单线程,不支持直接阻塞,要完成阻塞还是得写 async 和 await 才能达成目的,看着很奇怪…
同步用 Python 贴出来算了…
创建 Promise 对象
手动创建一个 Promise 对象并在其他异步函数中获取它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function fetchUserData(userId: string) { return new Promise((resolve, reject) => { console.log("开始请求服务器..."); setTimeout(() => { if (userId === "123") { resolve({ name: "张三", age: 25 }); } else { reject(new Error("用户不存在")); } }, 2000); }); }
async function main() { try { const data = await fetchUserData("123"); console.log("成功了,数据是:", data); } catch (error) { console.log("失败了,错误是:", error.message); } }
|
结语
TypeScript 写起来确实舒服,比刚开始写 JavaScript 要舒服些。但是由于没有打好基础,写起来是真的艰难…
遇到问题就更新…