Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • 数据类型

    • 初识typescript及数据类型
      • TypeScript 是什么?
      • 一、TypeScript 解决什么问题
        • JS 的典型痛点
        • TS 的改进
      • 二、TypeScript 的基本使用方式
        • 1️⃣ 安装 & 编译(了解即可)
        • 2️⃣ 常见内置工具类型(必须认识)
      • 三、基础类型(最重要)
        • 1️⃣ 原始类型
        • 2️⃣ 数组
        • 3️⃣ 元组(固定长度 + 固定类型)
        • 4️⃣ 枚举(Enum)
      • 四、对象 & 接口(前端最常用)
        • 1️⃣ 直接写对象类型
        • 2️⃣ interface(强烈推荐)
        • 3️⃣ interface vs type(先记结论)
      • 五、函数类型(前端必会)
        • 1️⃣ 参数 & 返回值
        • 2️⃣ 可选参数 & 默认值
        • 可选参数
        • 默认参数
        • 3️⃣ 函数类型声明
        • 4️⃣ 剩余参数
        • 5️⃣ 函数重载
      • 六、联合类型 & 类型别名(非常常用)
        • 1️⃣ 联合类型(|)
        • 2️⃣ type(类型别名)
      • 七、any / unknown(一定要懂)
        • 1️⃣ any(不推荐)
        • 2️⃣ unknown(安全版 any)
      • 八、null 和 undefined
      • 九、 void 类型
      • 十、 特殊类型
        • 1️⃣ never 类型
        • 2️⃣ strictNullChecks
        • 3️⃣ never 和 void 的区别
      • 十一、 Symbol
      • 十二、 BigInt
      • 十三、类型推导(TS 的“智能”)
      • 十四、断言(你“比 TS 更清楚”)
        • 1️⃣ 类型推断(TS 的灵魂)
        • 2️⃣ 类型断言(as)
      • 十五、字面量类型和类型字面量
      • 十六、字符串字面量 vs 联合类型
      • 十七、TS 在前端框架中的典型用法
        • React Props
        • Vue3 + defineProps
      • 十八、你下一步该学什么(路线建议)
        • 🔹 第 1 阶段(你现在)
        • 🔹 第 2 阶段(进阶必学)
        • 🔹 第 3 阶段(高手)
    • 类
    • 接口
    • 泛型
    • 结构类型系统
    • 类型保护
    • 类型变换
    • 模块和命名空间
    • 类型声明
    • null和undefined
  • 实践应用

  • 《TypeScript》学习笔记
  • 数据类型
mamingjuan
2020-10-04
目录

初识typescript及数据类型

# TypeScript 是什么?

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

一句话:

TS = 带类型的 JavaScript


# 一、TypeScript 解决什么问题

一句话:

TypeScript = JavaScript + 类型系统

# JS 的典型痛点

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

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

# TS 的改进

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

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

TS 的核心价值

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

# 二、TypeScript 的基本使用方式

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

npm install typescript -g
tsc index.ts
1
2

大多数前端项目里:

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

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

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

type UserBase = Pick<User, 'id' | 'name'>
1
2
3
4
5
6
7

# 三、基础类型(最重要)

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

console.log((new String('hello ')).toUpperCase());
1
2
3
4

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

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

# 1️⃣ 原始类型

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;
1
2
3
4
5
6
7

# 2️⃣ 数组

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

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

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

常用于:

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

# 4️⃣ 枚举(Enum)

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}`);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • 常数枚举与普通枚举的区别是,常数枚举会在编译阶段被删除,并且不能包含计算成员。
  • 假如包含了计算成员,则会在编译阶段报错
const enum Colors {
    Red,
    Yellow,
    Blue
}

let myColors = [Colors.Red, Colors.Yellow, Colors.Blue];
const enum Color {Red, Yellow, Blue = "blue".length};
1
2
3
4
5
6
7
8

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


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

# 1️⃣ 直接写对象类型

const user: {
  name: string
  age: number
} = {
  name: 'Tom',
  age: 18
}
1
2
3
4
5
6
7

# 2️⃣ interface(强烈推荐)

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

const u: User = {
  name: 'Tom',
  age: 18
}
1
2
3
4
5
6
7
8
9
10

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

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

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

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

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

# 1️⃣ 参数 & 返回值

function add(a: number, b: number): number {
  return a + b
}
1
2
3

没有返回值

let hello2 = function (name: string):void {
    console.log('hello2', name);
    return undefined;
}
hello2('hello ');
1
2
3
4
5

# 2️⃣ 可选参数 & 默认值

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

# 可选参数

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

# 默认参数

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

# 3️⃣ 函数类型声明

定义函数类型

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

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

# 4️⃣ 剩余参数

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

# 5️⃣ 函数重载

  • 在Java中的重载,指的是两个或者两个以上的同名函数,参数不一样
  • 在TypeScript中,表现为给同一个函数提供多个函数类型定义
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
2
3
4
5
6
7
8
9
10
11
12
13
14

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

# 1️⃣ 联合类型(|)

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

export {};
1
2
3
4
5
6
7
8
let id: number | string

id = 1
id = '1'
1
2
3
4

# 2️⃣ type(类型别名)

type ID = number | string

type User = {
  id: ID
  name: string
}
1
2
3
4
5
6

# 七、any / unknown(一定要懂)

# 1️⃣ any(不推荐)

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

# 2️⃣ unknown(安全版 any)

let x: unknown

if (typeof x === 'string') {
  x.toUpperCase() // ✅
}
1
2
3
4
5

👉 经验法则

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

# 八、null 和 undefined

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

let y: number | null | undefined;
y = 1;
y = undefined;   
y = null; 
1
2
3
4
5
6
7
8
9

# 九、 void 类型

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

# 十、 特殊类型

# 1️⃣ never 类型

  • 作为不会返回( return )的函数的返回值类型
// 返回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) {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2️⃣ strictNullChecks

  • 在 TS 中, null 和 undefined 是任何类型的有效值,所以无法正确地检测它们是否被错误地使用。于是 TS 引入了 --strictNullChecks 这一种检查模式
  • 由于引入了 --strictNullChecks ,在这一模式下,null 和 undefined 能被检测到。所以 TS 需要一种新的底部类型( bottom type )。所以就引入了 never。
// 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 无法被观察
  }
}
1
2
3
4
5
6
7
8
9
10
11

# 3️⃣ never 和 void 的区别

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

# 十一、 Symbol

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

# 十二、 BigInt

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

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

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

函数返回值也能推导:

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

👉 写 TS 的正确姿势

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

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

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

双重断言

interface Person {
    name: string;
    age: number;
}
const person = 'hello ' as any as Person; // ok
1
2
3
4
5

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

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

❗能不写就不写类型


# 2️⃣ 类型断言(as)

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

⚠️ 断言 ≠ 转换 只是告诉 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");
1
2
3
4
5
6
7
type Person = {
  name:string,
  age:number
};
1
2
3
4

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

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

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

# React Props

interface Props {
  title: string
  count?: number
}

function MyComp({ title, count = 0 }: Props) {
  return <div>{title} {count}</div>
}
1
2
3
4
5
6
7
8

# Vue3 + defineProps

interface Props {
  msg: string
}

const props = defineProps<Props>()
1
2
3
4
5

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

# 🔹 第 1 阶段(你现在)

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

# 🔹 第 2 阶段(进阶必学)

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

# 🔹 第 3 阶段(高手)

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

上次更新: 2026/01/07, 09:20:46
类

类→

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式