Menu

TypeScript 和 Python 的区别:类型、速度与用途对比

TypeScript 和 Python 都是带垃圾回收的高级语言,但 TypeScript 在代码运行前检查类型,而 Python 的类型提示是可选的,运行时会被忽略。本文从类型、运行时、速度、生态和用途几个方面并排对比两者,并用两种语言写同一个程序。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

TypeScript 和 Python 都是高级语言,都有垃圾回收、一等函数和庞大的包生态。主要区别在于类型:TypeScript 的类型由编译器在程序运行之前检查,而 Python 的类型提示是可选的注解,解释器会忽略它们。两者还运行在不同的引擎上,主导着不同类型的软件:TypeScript 主导 Web,Python 主导数据处理和脚本。

下面是一个用 TypeScript 写的小程序。点击“运行”:

输出:

162.25
[ 'Ada', 'Grace', 'Linus' ]

用 Python 写同一个程序,并加上类型提示:

from dataclasses import dataclass


@dataclass
class Order:
    customer: str
    amount: float
    paid: bool


def total_paid(orders: list[Order]) -> float:
    return sum(o.amount for o in orders if o.paid)


orders = [
    Order("Ada", 120.0, True),
    Order("Grace", 80.5, False),
    Order("Linus", 42.25, True),
]

by_amount = [o.customer for o in sorted(orders, key=lambda o: o.amount, reverse=True)]
print(total_paid(orders))
print(by_amount)
162.25
['Ada', 'Grace', 'Linus']

两者的结构很接近:一个描述记录的类型、一个带类型参数的函数、一个值的列表。看得见的区别在于语法(花括号和分号对比缩进)、interface 对比 @dataclass,以及箭头函数配合 filter/reduce 对比生成器表达式。

TypeScript 与 Python 一览

TypeScriptPython
类型静态,在编译期检查;运行时类型被擦除动态;类型提示可选,运行时不强制执行
类型检查器tsc,语言自带独立工具:mypy、pyright 等
运行环境JavaScript 引擎:浏览器、Node.js、Deno、BunCPython(标准解释器)、PyPy 等
执行方式编译成 JavaScript,再由引擎即时编译(JIT)在 CPython 中解释执行字节码
代码块花括号 { }缩进
数字number(64 位浮点数)和 bigintint(任意大小)和 float
并发每个事件循环一个线程,async/await;并行任务用 workerasyncio、线程、多进程
包管理器npm、pnpm、Yarn、Bunpip、uv、Poetry
最擅长的领域Web 前端、Node.js 后端、全栈应用数据科学、机器学习、脚本、自动化、后端

语法对照

如果你熟悉 Python 的类型提示,大多数 TypeScript 注解都有直接对应的写法:

PythonTypeScript
count: int = 0let count: number = 0;
def add(a: int, b: int) -> int:function add(a: number, b: number): number {
lambda x: x * 2(x) => x * 2
list[str]string[]
dict[str, int]Record<string, number> 或 Map<string, number>
tuple[int, str][number, string]
str | Nonestring | null 或 string | undefined
Literal["asc", "desc"]"asc" | "desc"
Callable[[int], str](n: number) => string
TypedDictinterface 或 type
@dataclassclass,纯数据可用 interface
Anyany
None、True、Falsenull(或 undefined)、true、false
and、or、not&&、||、!
f"Hello {name}"`Hello ${name}`

静态类型与类型提示

两种语言都能写出同样的注解,a: number 或 a: int。但接下来发生的事情不同。

在 TypeScript 中,编译器会在任何代码运行之前检查每一次调用。参数类型不对,构建就会停止:

index.ts(7,17): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

在 Python 中,类型提示只是元数据。解释器照常执行调用,并返回一个字符串:

def add(a: int, b: int) -> int:
    return a + b


print(add(2, 3))      # 5
print(add("2", "3"))  # 23, the hints are not enforced

检查是用 mypy 这类工具完成的一个独立步骤:

$ mypy hints.py
hints.py:6: error: Argument 1 to "add" has incompatible type "str"; expected "int"  [arg-type]
hints.py:6: error: Argument 2 to "add" has incompatible type "str"; expected "int"  [arg-type]
Found 2 errors in 1 file (checked 1 source file)

所以 Python 的类型系统在设计上是渐进式的:没有注解的代码根本不会被检查,你只在有帮助的地方添加类型提示。TypeScript 也可以很宽松(any 会关闭对某个值的检查),但在默认开启的 strict 模式下,没有注解的参数会报错,而不是直接放行。

两者有一个共同点:都不会在程序运行时检查类型。TypeScript 会擦除类型,Python 会忽略类型提示。运行时传入的数据,例如来自 API 的 JSON,在两种语言中都需要校验(TypeScript 的 Zod 和 Python 的 Pydantic 这类库可以根据 schema 完成校验)。

数字的行为不同

TypeScript 沿用 JavaScript 的数字:number 是 64 位浮点数,整数和小数都用它表示,bigint 则是专门用于大整数的独立类型。Python 的 int 会自动增长到任意大小。

输出:

0.30000000000000004
9007199254740992
3.5 3
1267650600228229401496703205376n

对于 2**53 + 1,Python 输出 9007199254740993,因为它的整数在任何大小下都是精确的;Python 还有专门的整除运算符 7 // 2,结果是 3。TypeScript 中没有 int 类型;整数只是恰好没有小数部分的 number。

运行时与性能

TypeScript 以 JavaScript 的形式运行。V8(用于 Chrome 和 Node.js)、JavaScriptCore(用于 Safari 和 Bun)和 SpiderMonkey(用于 Firefox)会在运行时把热点代码编译成机器码,所以 TypeScript 中的密集循环通常比 CPython 中同样的循环快得多,因为 CPython 执行的是字节码。

对很多程序来说,这个差距并没有听起来那么重要:

  • Python 的数值计算和机器学习库(NumPy、pandas、PyTorch)在编译好的 C、C++ 或 CUDA 代码中完成繁重的工作,所以调用它们的 Python 程序,其内层循环并不是在 Python 中运行的。
  • 无论用哪种语言写的 Web 服务器,大部分时间都在等待数据库和网络。

两种语言的大部分代码都运行在一个主线程上。Node.js 上的 TypeScript 用事件循环和 async/await 处理并发,用工作线程处理并行的 CPU 任务。Python 有 asyncio 提供同样风格的并发,此外还有线程和进程。

生态与用途

TypeScript 是以下领域的默认选择:

  • Web 前端:React、Angular、Vue 和 Svelte 都支持它,它会编译成浏览器运行的 JavaScript。
  • Node.js、Deno 和 Bun 上的服务器代码:用 Express、Fastify、NestJS 或 Hono 编写的 API。
  • 服务器和浏览器共享类型定义的全栈应用,例如 Next.js 项目。
  • 开发工具、命令行工具,以及用 Electron 开发的桌面应用。

Python 是以下领域的默认选择:

  • 数据分析和可视化(pandas、NumPy、Matplotlib、Jupyter notebook)。
  • 机器学习和 AI(PyTorch、scikit-learn,以及大部分模型训练代码)。
  • 脚本和自动化:文件处理、系统管理、胶水代码。
  • 用 Django、Flask 或 FastAPI 开发的 Web 后端。
  • 科学计算和教学。

Web 后端开发是两者重叠最多的地方。团队通常根据技术栈的其余部分来选择:要和 TypeScript 前端共享代码就选 TypeScript,要和数据及机器学习代码放在一起就选 Python。

应该学哪一个?

  • 做 Web 开发? 先学 JavaScript,再学 TypeScript。浏览器中运行的一切最终都是 JavaScript,而大多数专业的前端代码都是用 TypeScript 写的。
  • 做数据、AI 或自动化? 学 Python。它在这些领域的库,在 JavaScript 世界里没有真正的替代品。
  • 第一门语言,还没有明确目标? Python 需要学的语法更少,就能写出有用的程序。TypeScript 在 JavaScript 之上加了一套类型系统,一开始需要多学一些,但随着程序变大会越来越有回报。

很多开发者两者都用:Python 处理数据和脚本,TypeScript 编写产品的 Web 代码。如果你已经熟悉 Python 的类型提示,TypeScript 的注解会让你觉得眼熟;新的地方在于编译器默认强制执行它们,而底层的运行时是 JavaScript。

常见问题

TypeScript 比 Python 好吗?

总体上谁也不比谁好,它们各自在不同领域领先。TypeScript 是 Web 前端的标准选择,在 Node.js 服务器中也很常见,类型检查是日常开发流程的一部分。Python 在数据科学、机器学习、脚本和自动化领域领先,它的类型提示可以用 mypy 或 pyright 等工具检查。

TypeScript 比 Python 快吗?

对于用语言本身编写的 CPU 密集型代码,通常是的:TypeScript 编译成 JavaScript,V8 这样的引擎会在运行时把它编译成机器码,而 Python 的标准解释器 CPython 执行的是字节码。主要时间花在 C 语言编写的库(NumPy、pandas、PyTorch)中的 Python 程序不受此限制;对于受网络限制的服务器,差别往往也很小。

Python 有像 TypeScript 那样的静态类型吗?

Python 有可选的类型提示(def add(a: int, b: int) -> int),但解释器不会强制执行它们:add("2", "3") 能运行并返回 "23"。需要用 mypy 或 pyright 这样的独立检查工具来报告类型不匹配。在 TypeScript 中,检查是编译器的主要工作,项目通常配置为存在类型错误的代码无法构建。

应该先学 TypeScript 还是 Python?

根据你想做的东西来选。要做网站和 Web 应用,先学 JavaScript,再学 TypeScript,因为浏览器只运行 JavaScript。要做数据分析、机器学习、自动化,或者想找一门语法很少的入门语言,就从 Python 开始。无论选哪个,核心概念(变量、函数、循环、对象)都可以迁移。

Coddy 编程语言插图

和 Coddy 一起学编程

开始