Skip to content

TypeScript 是什么?

项目说明
本质JavaScript 的 超集
作用给 JS 增加 类型系统
运行时❌ 不能直接运行,需要编译成 JS
编译器tsc
核心价值类型安全 + IDE 智能提示 + 可维护性

一句话:

TS = 带类型的 JavaScript

一、TypeScript 解决什么问题

一句话

TypeScript = JavaScript + 类型系统

JS 的典型痛点

js
function sum(a, b) {
  return a + b
}

sum(1, '2') // 🤯 运行时才发现是 "12"

TS 的改进

ts
function sum(a: number, b: number): number {
  return a + b
}

sum(1, '2') // ❌ 编译期直接报错

TS 的核心价值

  • ❌ 少踩坑(提前发现错误)
  • 🧠 更好的代码提示 & 自动补全
  • 🔧 重构更安全
  • 📐 更适合大型项目(React / Vue3 / Node)

二、TypeScript 的基本使用方式

1️⃣ 安装 & 编译(了解即可)

bash
npm install typescript -g
tsc index.ts

大多数前端项目里:

  • Vite / Vue / React 已经 内置 TS 支持
  • 你几乎不用手动跑 tsc

2️⃣ 常见内置工具类型(必须认识)

工具类型作用
Partial<T>变可选
Required<T>变必选
Pick<T, K>取部分字段
Omit<T, K>排除字段
Record<K, T>key-value 对象
ts
type User = {
  id: number
  name: string
  age: number
}

type UserBase = Pick<User, 'id' | 'name'>

三、基础类型(最重要)

  • JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)。
  • 所有的原始数据类型都没有属性(property)
ts
let name = 'hello ';
console.log(name.toUpperCase());

console.log((new String('hello ')).toUpperCase());

当调用基本数据类型方法的时候,JavaScript 会在原始数据类型和对象类型之间做一个迅速的强制性切换

ts
let isOK: boolean = true; // 编译通过
let isOK: boolean = Boolean(1) // 编译通过
let isOK: boolean = new Boolean(1); // 编译失败   期望的 isOK 是一个原始数据类型

1️⃣ 原始类型

ts
let a: number = 1
let b: string = 'hello'
let c: boolean = true
let d: null = null
let e: undefined = undefined
let id: symbol = Symbol("unique");
let bigNumber: bigint = 123n;

2️⃣ 数组

ts
let arr1: number[] = [1, 2, 3]
let arr2: Array<string> = ['a', 'b']

3️⃣ 元组(固定长度 + 固定类型)

ts
let tuple: [string, number] = ['age', 18]

常用于:

  • useState
  • 返回固定结构的数据
元组数组
每一项可以是不同的类型每一项都是同一种类型
有预定义的长度没有长度限制
用于表示一个固定的结构用于表示一个列表
ts
const animal:[string,number,boolean] = ['hello ',10,true];

4️⃣ 枚举(Enum)

ts
enum Status {
  Pending,
  Success,
  Error
}

let s: Status = Status.Success

// 普通枚举
enum Gender{
    GIRL,
    BOY
}
console.log(`李雷是${Gender.BOY}`);
console.log(`韩梅梅是${Gender.GIRL}`);

// 常数枚举
enum Week{
    MONDAY=1,
    TUESDAY=2
}
console.log(`今天是星期${Week.MONDAY}`);
  • 常数枚举与普通枚举的区别是,常数枚举会在编译阶段被删除,并且不能包含计算成员。
  • 假如包含了计算成员,则会在编译阶段报错
ts
const enum Colors {
    Red,
    Yellow,
    Blue
}

let myColors = [Colors.Red, Colors.Yellow, Colors.Blue];
const enum Color {Red, Yellow, Blue = "blue".length};

📌 实战中 更推荐联合类型替代 enum(后面讲)

四、对象 & 接口(前端最常用)

1️⃣ 直接写对象类型

ts
const user: {
  name: string
  age: number
} = {
  name: 'Tom',
  age: 18
}

2️⃣ interface(强烈推荐

ts
interface User {
  name: string
  age: number
  isAdmin?: boolean // 可选
}

const u: User = {
  name: 'Tom',
  age: 18
}

React props / Vue props / API 返回值 中大量使用

3️⃣ interface vs type(先记结论)

对比interfacetype
对象✅ 强
联合
扩展extends&
React / Vue常用常用

五、函数类型(前端必会)

  • 可以指定参数的类型和返回值的类型

1️⃣ 参数 & 返回值

ts
function add(a: number, b: number): number {
  return a + b
}

没有返回值

ts
let hello2 = function (name: string):void {
    console.log('hello2', name);
    return undefined;
}
hello2('hello ');

2️⃣ 可选参数 & 默认值

  • 在TS中函数的形参和实参必须一样,不一样就要配置可选参数,而且必须是最后一个参数
ts
function greet(name: string, age?: number) {} // age为可选参数
function greet2(name: string, age = 18) {} // age设置了默认值

可选参数

ts
function print(name: string, age?: number):void {
    console.log(name, age);
}
print('hahaha ');

默认参数

ts
function ajax(url: string, method: string='GET') {
    console.log(url, method);
}
ajax('/users');

3️⃣ 函数类型声明

定义函数类型

ts
type GetUsernameFunction = (x: string, y: string)=>string;
let getUsername:GetUsernameFunction = function(firstName, lastName){
  return firstName + lastName;
}
ts
type Fn = (a: number, b: number) => number

const add: Fn = (a, b) => a + b

4️⃣ 剩余参数

ts
function sum(...numbers:number[]) {
    return numbers.reduce((val,item)=>val+=item,0);
}
console.log(sum(1,2,3));

5️⃣ 函数重载

  • 在Java中的重载,指的是两个或者两个以上的同名函数,参数不一样
  • 在TypeScript中,表现为给同一个函数提供多个函数类型定义
ts
let obj: any = {};
function attr(val: string): void;
function attr(val: number): void;
function attr(val: any):void {
    if (typeof val === 'string') {
        obj.name = val;
    } else {
        obj.age = val;
    }
}
attr('hahaha');
attr(9);
attr(true);
console.log(obj);

六、联合类型 & 类型别名(非常常用)

1️⃣ 联合类型(|)

  • 联合类型(Union Types)表示取值可以为多种类型中的一种
  • 未赋值时联合类型上只能访问两个类型共有的属性和方法
ts
let name: string | number;
console.log(name.toString());
name = 3;
console.log(name.toFixed(2));
name = 'hello ';
console.log(name.length);

export {};
ts
let id: number | string

id = 1
id = '1'

2️⃣ type(类型别名)

ts
type ID = number | string

type User = {
  id: ID
  name: string
}

七、any / unknown(一定要懂)

1️⃣ any(不推荐)

  • any就是可以赋值给任意类型
  • 第三方库没有提供类型文件时可以使用any
  • 类型转换遇到困难时
  • 数据结构太复杂难以定义
ts
let a: any = 1
a.foo.bar() // TS 不管,运行时可能炸
ts
let root:any=document.getElementById('root');
root.style.color='red';
ts
let root:(HTMLElement|null)=document.getElementById('root');
root!.style.color='red';//非空断言操作符

2️⃣ unknown(安全版 any)

ts
let x: unknown

if (typeof x === 'string') {
  x.toUpperCase() // ✅
}

👉 经验法则

  • 能不用 any 就不用
  • 接口数据不确定 → unknown + 类型守卫

八、null 和 undefined

  • null 和 undefined 是其它类型的子类型,可以赋值给其它类型,如数字类型,此时,赋值后的类型会变成 null 或 undefined
  • strictNullChecks 参数用于新的严格空检查模式,在严格空检查模式下, null 和 undefined 值都不属于任何一个类型,它们只能赋值给自己这种类型或者 any
ts
let x: number;
x = 1;
x = undefined;    
x = null;   

let y: number | null | undefined;
y = 1;
y = undefined;   
y = null;

九、 void 类型

  • void 表示没有任何类型
  • 当一个函数没有返回值时,TS 会认为它的返回值是 void 类型。
ts
function greeting(name:string):void {
    console.log('hello',name);
    //当我们声明一个变量类型是 void 的时候,它的非严格模式(strictNullChecks:false)下仅可以被赋值为 null 和 undefined
    //严格模式(strictNullChecks:true)下只能返回undefined
    //return null;
    //return undefined;
}

十、 特殊类型

1️⃣ never 类型

  • 作为不会返回( return )的函数的返回值类型
ts
// 返回never的函数 必须存在 无法达到( unreachable ) 的终点
function error(message: string): never {
    throw new Error(message);
}
let result1 = error('hello');
// 由类型推论得到返回值为 never
function fail() {
    return error("Something failed");
}
let result = fail();

// 返回never的函数 必须存在 无法达到( unreachable ) 的终点
function infiniteLoop(): never {
    while (true) {}
}

2️⃣ strictNullChecks

  • 在 TS 中, null 和 undefined 是任何类型的有效值,所以无法正确地检测它们是否被错误地使用。于是 TS 引入了 --strictNullChecks 这一种检查模式
  • 由于引入了 --strictNullChecks ,在这一模式下,null 和 undefined 能被检测到。所以 TS 需要一种新的底部类型( bottom type )。所以就引入了 never。
ts
// Compiled with --strictNullChecks
function fn(x: number | string) {
  if (typeof x === 'number') {
    // x: number 类型
  } else if (typeof x === 'string') {
    // x: string 类型
  } else {
    // x: never 类型
    // --strictNullChecks 模式下,这里的代码将不会被执行,x 无法被观察
  }
}

3️⃣ never 和 void 的区别

  • void 可以被赋值为 null 和 undefined的类型。 never 则是一个不包含值的类型。
  • 拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。

十一、 Symbol

  • 我们在使用 Symbol 的时候,必须添加 es6 的编译辅助库
  • Symbol 是在ES2015之后成为新的原始类型,它通过 Symbol 构造函数创建
  • Symbol 的值是唯一不变的
ts
const sym1 = Symbol('key');
const sym2 = Symbol('key');
Symbol('key') === Symbol('key') // false

十二、 BigInt

  • 使用 BigInt 可以安全地存储和操作大整数
  • 我们在使用 BigInt 的时候,必须添加 ESNext 的编译辅助库
  • 要使用1n需要 "target": "ESNext"
ts
// number和 BigInt类型不一样,不兼容
const max = Number.MAX_SAFE_INTEGER;// 2**53-1
ts
console.log(max + 1 === max + 2);
const max = BigInt(Number.MAX_SAFE_INTEGER);
ts
console.log(max + 1n === max + 2n);
let foo: number;
let bar: bigint;
foo =bar;
bar = foo;

十三、类型推导(TS 的“智能”)

  • 是指编程语言中能够自动推导出值的类型的能力,它是一些强静态类型语言中出现的特性
  • 定义时未赋值就会推论成any类型
  • 如果定义的时候就赋值就能利用到类型推论
ts
let num = 1       // 推导为 number
let str = 'abc'   // 推导为 string

函数返回值也能推导:

ts
function add(a: number, b: number) {
  return a + b // 自动推导 number
}

👉 写 TS 的正确姿势

  • 能推导就不写
  • 对外 API / 函数边界写清楚

十四、断言(你“比 TS 更清楚”)

  • 类型断言可以将一个联合类型的变量,指定为一个更加具体的类型
  • 不能将联合类型断言为不存在的类型
ts
let name: string | number;
console.log((name as string).length);
console.log((name as number).toFixed(2));
console.log((name as boolean));

双重断言

ts
interface Person {
    name: string;
    age: number;
}
const person = 'hello ' as any as Person; // ok

1️⃣ 类型推断(TS 的灵魂)

ts
let num = 1 // 自动推断为 number

能不写就不写类型

2️⃣ 类型断言(as)

ts
const img = document.querySelector('img') as HTMLImageElement

⚠️ 断言 ≠ 转换 只是告诉 TS「我比你清楚」

⚠️ 谨慎使用,断言 ≠ 类型检查

十五、字面量类型和类型字面量

  • 字面量类型的要和实际的值的字面量一一对应,如果不一致就会报错
  • 类型字面量和对象字面量的语法很相似
ts
const up:'Up'= 'Up';
const down: "Down" = "Down";
const left: "Left" = "Left";
const right: "Right" = "Right";
type Direction = 'Up' | 'Down' | 'Left' | 'Right';
function move(direction: Direction) {}
move("Up");
ts
type Person = {
  name:string,
  age:number
};

十六、字符串字面量 vs 联合类型

  • 字符串字面量类型用来约束取值只能是某几个字符串中的一个, 联合类型(Union Types)表示取值可以为多种类型中的一种
  • 字符串字面量 限定了使用该字面量的地方仅接受特定的值,联合类型 对于值并没有限定,仅仅限定值的类型需要保持一致

十七、TS 在前端框架中的典型用法

React Props

ts
interface Props {
  title: string
  count?: number
}

function MyComp({ title, count = 0 }: Props) {
  return <div>{title} {count}</div>
}

Vue3 + defineProps

ts
interface Props {
  msg: string
}

const props = defineProps<Props>()

十八、你下一步该学什么(路线建议)

🔹 第 1 阶段(你现在)

  • 基础类型
  • interface / type
  • 联合类型
  • 函数类型
  • 类型推导

🔹 第 2 阶段(进阶必学)

  • 泛型 <T>
  • keyof / typeof
  • 映射类型
  • 条件类型
  • TS 在 React / Vue 中的最佳实践

🔹 第 3 阶段(高手)

  • 类型工具
  • 给组件库 / hooks 写类型
  • 阅读 Vue / React 源码里的 TS