TypeScript 01:环境与基础语法
1. 环境搭建
```bash
# 安装 Node.js(建议 LTS 版本,macOS 可用 brew)
brew install node
node -v && npm -v
# 新建练习项目
mkdir ts-learn && cd ts-learn
npm init -y
npm install -D typescript tsx @types/node
npx tsc --init # 生成 tsconfig.json
# 运行 TS 文件(tsx 可直接运行,无需先编译,类似 python xxx.py)
npx tsx hello.ts
对照:
npm≈pip,package.json≈pyproject.toml,node_modules/≈.venv/site-packages,npx≈python -m。
hello.ts:
const name: string = "TypeScript";
console.log(`Hello, ${name}!`); // 模板字符串 ≈ Python 的 f-string
2. 变量与基本类型
let count: number = 10; // 可重新赋值
const PI = 3.14; // 常量,类型自动推断为 3.14(字面量类型)
let title = "blog"; // 推断为 string,不必每处都写类型
let isActive: boolean = true;
let nothing: null = null;
let notAssigned: undefined = undefined;
let anything: unknown = 42; // 安全版 any,使用前必须先判断类型
| Python | C# | TypeScript |
|---|---|---|
int/float |
int/double |
number(只有一种数字) |
str |
string |
string |
bool |
bool |
boolean |
None |
null |
null/undefined |
Any |
object/dynamic |
any(避免)/unknown(推荐) |
规则:默认用
const,需要重新赋值才用let,永远不要用var。
3. 数组、元组、对象
// 数组 ≈ list
const tags: string[] = ["python", "go"];
tags.push("ts");
const upper = tags.map(t => t.toUpperCase()); // [x.upper() for x in tags]
const longTags = tags.filter(t => t.length > 2); // [x for x in tags if len(x) > 2]
const total = [1, 2, 3].reduce((sum, n) => sum + n, 0); // sum([1,2,3])
// 元组 ≈ tuple
const point: [number, number] = [10, 20];
const [x, y] = point; // 解构 ≈ x, y = point
// 对象 ≈ dict(但更像 C# 的匿名对象)
const post = { id: 1, title: "Hello", tags: ["ts"] };
console.log(post.title, post["title"]);
const { id, title: postTitle } = post; // 解构并重命名
// 展开运算符 ≈ Python 的 {**a, **b} 和 [*a, *b]
const updated = { ...post, title: "New Title" };
const merged = [...tags, "rust"];
4. 函数
// 普通函数
function add(a: number, b: number): number {
return a + b;
}
// 箭头函数(最常用,≈ lambda 但可以多行)
const multiply = (a: number, b: number): number => a * b;
// 可选参数 & 默认值
function greet(name: string, greeting = "Hello", suffix?: string): string {
return `${greeting}, ${name}${suffix ?? ""}`;
}
// 剩余参数 ≈ *args
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0);
}
// "关键字参数":TS 没有 kwargs,惯用法是传一个对象
function createUser({ name, age = 18 }: { name: string; age?: number }) {
return { name, age };
}
createUser({ name: "Tom" });
5. 控制流与常用运算符
for (const tag of tags) { } // 遍历值 ≈ for tag in tags
for (const [i, tag] of tags.entries()) { } // ≈ enumerate
for (const key in post) { } // 遍历对象 key(少用)
Object.entries(post).forEach(([k, v]) => console.log(k, v)); // ≈ dict.items()
// 严格相等:永远用 === 和 !==
if (count === 10) { }
// 空值合并 ?? 与 可选链 ?.(C# 也有)
const user: { profile?: { email?: string } } = {};
const email = user.profile?.email ?? "unknown";
坑:
||会把0、""也当成假值;需要只判断 null/undefined 时用??。
6. 类(与 C# 非常像)
class Account {
private balance = 0;
constructor(public readonly owner: string) {} // 参数属性:自动声明并赋值
deposit(amount: number): void {
if (amount <= 0) throw new Error("amount must be positive");
this.balance += amount;
}
get current(): number { // ≈ Python @property
return this.balance;
}
}
const acc = new Account("bjiang");
acc.deposit(100);
console.log(acc.current);
实际项目中,TS 更偏向「函数 + 类型」的写法,类主要用于服务对象、Page Object 等。
7. 应用场景示例:把 Python 脚本改写成 TS
需求:读取一个 CSV 格式的记账文件,按分类汇总支出。
Python 版:
from collections import defaultdict
import csv
totals = defaultdict(float)
with open("expense.csv") as f:
for row in csv.DictReader(f):
totals[row["category"]] += float(row["amount"])
print(dict(totals))
TypeScript 版(expense.ts):
import { readFileSync } from "node:fs";
type Expense = { date: string; category: string; amount: number };
function parseCsv(path: string): Expense[] {
const [header, ...lines] = readFileSync(path, "utf-8").trim().split("\n");
const keys = header.split(",");
return lines.map(line => {
const values = line.split(",");
const row = Object.fromEntries(keys.map((k, i) => [k, values[i]]));
return { date: row.date, category: row.category, amount: Number(row.amount) };
});
}
function summarize(expenses: Expense[]): Record<string, number> {
const totals: Record<string, number> = {};
for (const e of expenses) {
totals[e.category] = (totals[e.category] ?? 0) + e.amount;
}
return totals;
}
console.table(summarize(parseCsv("expense.csv")));
expense.csv:
date,category,amount
2026-10-01,food,35.5
2026-10-01,transport,6
2026-10-02,food,42
运行:npx tsx expense.ts
8. 练习
- 给
summarize增加按月份汇总的功能,返回Record<string, Record<string, number>>。 - 写一个函数
topN(expenses, n),返回金额最大的 n 条记录(提示:[...arr].sort((a, b) => b.amount - a.amount).slice(0, n))。 - 故意把
amount写成字符串,观察tsc --noEmit报的错误。
文章评论 (0)