一文搞懂 TypeScript:为什么 JavaScript 需要类型?从 JS 到 TS 入门笔记

最近开始学习 TypeScript,发现很多项目已经默认使用 TS 开发了,例如 React、Vue、NestJS 等。

刚开始学习的时候,我一直有几个疑问:

  • JavaScript 为什么不需要声明类型?
  • 什么是动态语言?什么是静态语言?
  • TypeScript 到底是不是一门新的语言?
  • 为什么大家都说 TS 能提高代码质量?

这篇文章主要记录一下自己的学习过程,希望能帮助和我一样刚开始学习 TypeScript 的同学。


JavaScript 是一门弱类型动态语言

想理解 TypeScript,就要先理解 JavaScript。

JavaScript 有两个非常重要的特点:

  • 动态语言(Dynamic)
  • 弱类型语言(Weakly Typed)

什么是动态语言?

动态指的是:

复制代码
变量的类型是在程序运行时确定的。

JavaScript 代码交给 V8 引擎执行时,V8 会根据变量当前保存的数据来判断它是什么类型,然后再决定如何操作。

例如:

ini 复制代码
let num = 10

let str = "hello"

let flag = true

我们在声明变量的时候:

typescript 复制代码
并没有告诉 JavaScript:

这是 number

这是 string

这是 boolean

但是程序依然可以正常运行。

因为:

复制代码
V8 会在运行过程中自动判断变量类型。

这就是:

sql 复制代码
动态类型(Dynamic Typing)

什么是弱类型?

弱类型指的是:

复制代码
变量的类型可以随时改变。

例如:

ini 复制代码
let value = 100

value = "Hello"

value = true

同一个变量:

既可以保存数字。

也可以保存字符串。

甚至可以保存布尔值。

JavaScript 都不会报错。

因此:

复制代码
JavaScript 是弱类型语言。

JavaScript 为什么设计成这样?

JavaScript 最初的目标就是:

复制代码
简单、灵活、容易上手。

因此:

开发者不用声明变量类型。

写代码速度非常快。

但是:

灵活的同时也意味着:

复制代码
容易出现类型错误。

例如:

scss 复制代码
function add(a, b) {
  return a + b
}

add(1, 2)      // 3

add("1", 2)    // "12"

同一个函数:

不同类型会得到完全不同的结果。

大型项目中:

这种问题很难排查。


什么是强类型静态语言?

与 JavaScript 相反。

很多语言属于:

复制代码
强类型静态语言。

例如:

  • Java
  • Go
  • C#
  • Rust

它们都有两个特点。


静态类型

静态指的是:

复制代码
编译阶段就会检查变量类型。

例如:

Go:

csharp 复制代码
var age int = 18

Java:

ini 复制代码
int age = 18;

变量类型:

复制代码
写代码的时候

就已经确定了。

如果类型错误:

编译器直接报错。

不会等到程序运行。


强类型

强类型指的是:

复制代码
变量类型不能随意改变。

例如:

ini 复制代码
var age int = 18

age = "Hello"

编译器会直接报错。

因为:

c 复制代码
int

不能变成

string

因此:

复制代码
强类型语言

能够提前发现很多错误。

JavaScript 与强类型语言对比

JavaScript Java / Go
动态类型 静态类型
弱类型 强类型
运行时检查 编译时检查
不需要声明类型 必须声明类型

所以:

JavaScript 开发速度快。

而:

Java、Go 更安全。


TypeScript 是什么?

TypeScript 官方定义:

复制代码
TypeScript 是 JavaScript 的超集(Superset)。

什么意思?

就是说:

复制代码
所有 JavaScript 都是合法的 TypeScript。

例如:

JavaScript:

ini 复制代码
let name = "Rose"

TypeScript 同样可以运行。

但是:

TS 又新增了:

复制代码
类型系统。

例如:

ini 复制代码
let name: string = "Rose"

let age: number = 18

这样:

变量类型更加明确。


TypeScript 是一门新的语言吗?

不是。

TypeScript 本质还是:

复制代码
JavaScript。

只是:

增加了:

  • 类型检查
  • 编译时错误检查
  • 更完善的开发体验

浏览器:

复制代码
不能直接运行 TS。

因为:

浏览器只认识:

复制代码
JavaScript。

所以:

TypeScript 需要经过:

复制代码
TypeScript Compiler(tsc)

编译成:

复制代码
JavaScript。

然后浏览器再执行。

整个流程:

复制代码
TypeScript

↓

tsc 编译器

↓

JavaScript

↓

浏览器

TypeScript 为什么越来越流行?

最大的原因就是:

复制代码
大型项目需要类型。

例如:

一个团队:

几十个人一起开发。

如果:

javascript 复制代码
function getUser(data){}

没人知道:

kotlin 复制代码
data

到底是什么?

但是:

TypeScript:

javascript 复制代码
function getUser(data: User){}

一眼就知道:

sql 复制代码
参数必须是 User 类型。

阅读代码更加轻松。

维护成本也更低。


TypeScript 常见类型

学习 TS,首先要掌握类型系统。


基本类型

typescript 复制代码
let age: number = 18

let name: string = "Rose"

let isLogin: boolean = true

let a: null = null

let b: undefined = undefined

除此之外:

还有:

typescript 复制代码
symbol

bigint

any

swift 复制代码
let value: any

any 表示:

复制代码
关闭类型检查。

变量可以保存任何类型。

例如:

ini 复制代码
value = 10

value = "hello"

value = true

一般:

arduino 复制代码
不推荐大量使用 any。

否则:

TypeScript 就失去了意义。


object 与 Object

很多初学者容易混淆。

object

表示:

复制代码
狭义对象。

例如:

scss 复制代码
{}

[]

function(){}

Object

表示:

复制代码
广义对象。

几乎所有引用类型都属于:

css 复制代码
Object

数组与元组

数组:

ini 复制代码
let arr:number[]=[1,2,3]

元组:

ini 复制代码
let user:[string,number]

user=["Rose",18]

元组:

复制代码
长度固定。

每个位置类型固定。

Type

Type 可以:

复制代码
定义一个类型别名。

例如:

typescript 复制代码
type User={
    name:string
    age:number
}

以后:

sql 复制代码
let user:User

即可复用。


Interface

Interface:

主要用于:

复制代码
定义对象结构。

例如:

typescript 复制代码
interface User{
    name:string
    age:number
}

它与 Type 很相似。

但:

Interface 更适合描述对象。


泛型(Generic)

泛型可以理解成:

复制代码
类型参数。

例如:

r 复制代码
function getData<T>(value:T):T{
    return value
}

这样:

函数可以适配:

  • number
  • string
  • object

不用重复编写多个版本。


类型断言

有时候:

开发者比 TypeScript 更清楚变量类型。

可以使用:

csharp 复制代码
value as string

告诉编译器:

c 复制代码
我确定它是 string。

这就是:

python 复制代码
类型断言(Type Assertion)

keyof

keyof 可以获取:

对象所有键组成的联合类型。

例如:

typescript 复制代码
interface User{
    name:string
    age:number
}

得到:

sql 复制代码
keyof User

// "name" | "age"

它在封装工具函数时非常常见。


装饰器(Decorator)

装饰器本质上就是:

复制代码
给类、方法、属性

增加额外功能。

例如:

NestJS 中大量使用:

less 复制代码
@Controller()

@Get()

@Post()

@Injectable()

这些都是:

复制代码
Decorator。

我的理解

学习 TypeScript 后,我最大的感受就是:

JavaScript 更自由。

TypeScript 更规范。

对于小项目:

JavaScript 已经足够。

但是:

对于大型项目。

多人协作。

长期维护。

TypeScript 能提前发现很多问题。

因此:

现在越来越多的企业项目都会默认使用:

复制代码
TypeScript + React

TypeScript + Vue

TypeScript + Node.js

作为开发技术栈。


总结

一句话记住今天的内容:

复制代码
JavaScript 是一门弱类型动态语言,

变量类型在运行时确定,并且可以随意改变。

TypeScript 是 JavaScript 的超集,

它增加了类型系统和编译时检查,

帮助开发者在编码阶段发现错误,提高代码的可维护性和开发效率。
相关推荐
饼干哥哥1 天前
10.5% 深层转化、90%+ 新用户,ChatGPT Ads 值得吗?
算法·正则表达式·编程语言
清秋4 天前
全网最全 ECMAScript 攻略( 更新至 ES2026)
前端·javascript·编程语言
Jack201 个月前
HarmonyOS开发中请求拦截器链:日志、认证、重试
编程语言
Rust研习社1 个月前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
Jack201 个月前
HarmonyOS开发中RESTful API封装:网络层架构设计
编程语言
用户497863050731 个月前
(一)小红的数组操作
算法·编程语言
Rust研习社1 个月前
这 8 个 Rust 学习资源值得每个新手收藏起来
后端·rust·编程语言
Moonbit1 个月前
MoonBit ×CCF开源创新大赛 倒计时24天!快来提交你的作品
程序员·编程语言
Rust研习社1 个月前
Rust 错误处理的黄金搭档:一个定义错误,一个传播错误
后端·rust·编程语言