TypeScript速学

目录

[一、TypeScript 中的数据类型](#一、TypeScript 中的数据类型)

类型总览

类型声明

常用类型解析

字面量

any

unknown

never

void

类型限制

enum

数字枚举

字符串枚举

[const enum 常量枚举](#const enum 常量枚举)

自定义类型

[二、TypeScript 面向对象知识详解](#二、TypeScript 面向对象知识详解)

抽象类

常规类

继承

抽象类

接口

区别分析

属性修饰符

readonly

public

protected

private

泛型

三、补充知识点

JS的缺点以及TS的弥补

TS的特点以及使用场景

TS的搭建以及如何运行TS代码


(看不懂代码的,学习的部分可以自己手敲一遍,便于理解而且我的代码里都有注释)

一、TypeScript 中的数据类型

  • 包括JavaScript所有的数据类型:string、number、Boolean、null、undefined、bigint、symbol、object等
  • 四个新类型:void、never、unknown、any、enum、tuple
  • 自定义类型:type、interface

类型总览

  • 除了这三个构造函数: Number 、 String 、 Boolean ,他们只用于包装对象,正常开发很少去用,JS也是这样的

其他的都是常用类型

类型 描述 举例
number 任意数字 1 , -33 , 2.5
string 任意字符串 'hello' , 'ok' , ' 你好'
boolean 布尔值 true 或 false true、false
字面量 值只能是字面量 值本身
any 任意类型 1、'hello'、true ......
unknown 类型安全的 any 1、'hello'、true ......
never 不能是任何值 无值
void 空 或 undefined 空 或 undefined
object 任意的 JS 对象 {name:' 张三 '}
tuple 元素,TS 新增类型,固定长度数组 4,5
enum 枚举,TS 中新增类型 enum{A, B}

类型声明

可以看到,当给予的值不符合类型时会报错

函数也是一样的,接收不匹配类型,不符合数量的参数也会报错

上面的x和y都是number类型,但是参数一旦对不上或者不是number类型就会报错

常用类型解析

字面量

很明显可以看到,当变量被赋值时就已经固定了不能再被分配类型了,即使是同类型的值

any

any 的含义是:任意类型
⼀旦将变量类型限制为 any ,那就意味着放弃了对该变量的类型检查

TypeScript 复制代码
let a : any
a = 100
a = 'hello'
a = true

let b
b = 200
b = 'vue3'
b = false

这一段是都没有报错的

  • a被表明为any时对a的赋值都是没有报错的,这是any的显式
  • b没有表明类型时会被TS自动检测为any类型,这是any的隐式

注意点: any 类型的变量,可以赋值给任意类型的变量

TypeScript 复制代码
let a
let x: string
x = a

unknown

unknown 的含义是:未知类型

  • unknown 可以理解为⼀个类型安全的****any
  • unknown 适⽤于:开始不知道数据的具体类型,后期才能确定数据的类型

因为是安全类型的any,所以跟any还是有所不同的

TypeScript 复制代码
let a
let x: string
x = a

比如说这一个可以赋值给任意类型变量的用法,在unknown中就用不了

想要实现这个用法,有三种方法:

TypeScript 复制代码
let a: unknown
a = 'hello'
// 1、添加一个类型判断
if (typeof a === 'string') {
  x = a
}
// 2、加一个断言
x = a as string
// 3、加一个断言的另一个例子
x = <string>a

这里引入一个新的概念:

断言 -- 当TS也不知道当前变量是什么类型时,由我们来指定并告诉TS这个变量的类型

  • any 后点任何的东西都不会报错,而unknown 正好与之相反
  • 原因就是因为unknown遵循了安全检查逻辑,必须先确认类型才能用

never

never 的含义是:任何值都不是,简而言之就是不能有值

  • never不去限制变量,因为无论怎么样都会有报错

就是因为毫无意义,所以never的用法显得也有点多余,这里只要明确never的含义即可

void

void 的含义是:空 或 undefined ,严格来说null是不能赋值给void的

  • void常用于限制函数返回值
TypeScript 复制代码
function demo_1():void{
  return undefined
}

return undefined,空都是不会报错的

将其他类型的值分配给void就会报错

类型限制

Object几乎不用了因为其范围太大,TS在实际开发中,进行类型限制都用以下形式

  • 限制一般对象
TypeScript 复制代码
// 限制person对象的具体内容,问号代表可选属性
let person: {name: string, age?: number}

// 限制car对象的具体内容,用分号隔开,price和color是必填属性,其他属性可以是任意类型
let car: { price: number; color: string; [k:string]:any}

// 限制student对象的具体内容,使用回车分隔
let student : {
  id: string
  grade: number
} 

person = {name:"张三",age:18}
// 因为问号是可选属性所以age可以不写,也不会报错
person = {name:"李四"}
car = {price:10000,color:"红色"}
student = {id:"1001",grade:90}
  • 限制函数参数和返回值
TypeScript 复制代码
let demo : (a:number, b: number) => number

demo = function (x,y){
  return x+y
}
  • 限制数组
TypeScript 复制代码
let arr1: string[]
let arr2: number[] 

arr1 = ["a","b","c"]
arr2 = [1,2,3]

顺带一提,tuple 是⼀个长度固定的数组

enum

enum 是枚举

数字枚举
TypeScript 复制代码
enum Color{
  Red,
  Green,
  Blue,
}

enum Color2{
  Red = 4,
  Green,
  Blue,
}
字符串枚举
TypeScript 复制代码
enum Http {
  GET = "GET",
  POST = "POST",
  PUT = "PUT"
}
const method:Http = Http.POST
// Http["POST"] → undefined 取不到
const enum 常量枚举
TypeScript 复制代码
const enum Sex {Man=1,Woman=2}
let x = Sex.Man
//编译后:let x = 1,不生成Sex对象
//vite/isolatedModules:true 下用const enum会报错,换成普通enum

现在很多项目不用 enum,用 as const

TypeScript 复制代码
const Status = {
  OK:1,
  ERR:2
} as const
type StatusType = typeof Status[keyof typeof Status]

自定义类型

可以更加灵活的限制类型

TypeScript 复制代码
// 自定义一个类型,只能是1、2、3中的一个
type Grade = 1 | 2 | 3

// 自定义一个类型,包含id和grade两个属性
type Student = {
  id: string
  grade: Grade
}

let s1: Student
let s2: Student

s1 = {
  id:"1001",
  grade:1
}
s2 = {
  id:"1002",
  grade:2
}

二、TypeScript 面向对象知识详解

抽象类

常规类

TypeScript 复制代码
class Person {
    name: string
    age: number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
}


const p1 = new Person('张三',18)
const p2 = new Person('李四',19)

console.log(p1)
console.log(p2)

继承

TypeScript 复制代码
// Person类
class Person {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
}
// Teacher类继承Person
class Teacher extends Person {
  constructor(name: string, age: number) {
    super(name, age)
  }
}
// Student类继承Person
class Student extends Person {
  constructor(name: string, age: number) {
    super(name, age)
  }
}
// Person实例
const p1 = new Person('周杰伦',38)
// Student实例
const s1 = new Student('张同学',18)
const s2 = new Student('李同学',20)
// Teacher实例
const t1 = new Teacher('刘⽼师',40)
const t2 = new Teacher('孙⽼师',50)

抽象类

不能去实例化,但可以被别人继承,抽象类里有抽象方法

TypeScript 复制代码
// Person(抽象类)
abstract class Person {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  abstract speak(): void
}
// Teacher类继承Person
class Teacher extends Person {
 // 构造器
 constructor(name: string,age: number){
 super(name,age)
 }
 // ⽅法
 speak(){
 console.log('你好!我是⽼师:',this.name)
 }
}
// Student类继承Person
class Student extends Person {
  // 构造器
  constructor(name: string,age: number){
    super(name,age)
  }
  // ⽅法
  speak(){
    console.log('你好!我是学生:',this.name)
  }
}
// Person实例
// const p1 = new Person('周杰伦',38)

接口

  • 接口用于限制⼀个类中包含哪些属性和方法
TypeScript 复制代码
// Person接口
interface Person {
  name: string
  age: number
  speak(): void
}

// Teacher类实现Person接口
class Teacher implements Person {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  speak(): void {
  console.log('你好!我是老师:', this.name)
  }
}
  • 接口是可以重复声明的
TypeScript 复制代码
interface PersonInter {
  name: string
  age: number
}
interface PersonInter {
  speak(): void
}

class Person implements PersonInter {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  speak(): void {
    console.log('你好!我是', this.name)
  }
}

区别分析

与自定义类型的区别

  • 接口可以当自定义类型使用,还可以限制类的结构
TypeScript 复制代码
// 1.定义接口
interface User {
  name:string
  say():void
}
// 类用implements实现接口
class U implements User{
  name = "张三"
  say(){}
}
// 接口重复定义自动合并
interface User{age?:number}

与抽象类的区别

  • 接口只能有抽象方法,使用implements关键字去实现接口
  • 抽象类除了抽象方法还可以有普通方法 ,使用extends关键字去继承抽象类
TypeScript 复制代码
interface I {
  fn():void // 只有抽象,不能写方法体
}
class A implements I{
  fn(){}
}



abstract class Abs{
  abstract fn():void //抽象
  hello(){console.log(1)} //已有实现的普通方法
}
class B extends Abs{
  fn(){}
}

属性修饰符

修饰符 中文含义 可修改 / 访问范围
readonly 只读属性 仅可在声明时 / 构造函数内赋值,属性无法修改
public 公开的 可以在类内部、子类、外部对象中访问和修改
protected 受保护的 可以在类内部、子类中访问和修改,外部对象无法访问
private 私有的 仅可以在类内部访问和修改,子类、外部对象均无法访问

readonly

TypeScript 复制代码
class User {
  readonly id: number;
  name: string;
  constructor(id: number, name: string) {
    this.id = id; // 仅构造函数内可给readonly赋值
    this.name = name;
  }
}
const u = new User(1, "张三");
u.id = 2; // 报错:readonly 无法修改
u.name = "李四"; // 正常修改

public

TypeScript 复制代码
class User {
  public name: string;
  constructor(name: string) {
    this.name = name;
  }
}
const u = new User("张三");
u.name = "李四"; // 外部可直接修改

protected

TypeScript 复制代码
class User {
  protected name: string;
  constructor(name: string) {
    this.name = name;
  }
}
class VipUser extends User {
  changeName() {
    this.name = "VIP李四"; // 子类可修改
  }
}
const u = new User("张三");
u.name = "李四"; // 报错:外部对象无法访问

private

TypeScript 复制代码
class User {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
  changeName() {
    this.name = "李四"; // 仅类内部可修改
  }
}
class VipUser extends User {
  test() {
    this.name = "VIP"; // 报错:子类无法访问
  }
}
const u = new User("张三");
u.name = "李四"; // 报错:外部对象无法访问

泛型

定义⼀个函数或类时,有些情况下无法确定其中要使用的具体类型,此时就需要泛型了

  • <T> 就是泛型,(不⼀定非叫 T ),设置泛型后即可在函数中使用 T 来表示该类型
TypeScript 复制代码
function test<T>(arg: T): T {
  return arg
}
// 不指明类型,会自动推导类型
test(10)
// 指明类型,会强制转换为指定类型
test<number>(10)
  • 泛型可以写多个
TypeScript 复制代码
function test<T, U>(a: T, b: U): T {
  return a
}
// 调用时指定类型参数
test<number, string>(10, 'hello')
  • 类中同样可以使用泛型
TypeScript 复制代码
class MyClass<T>{
  prop: T;
  constructor(p: T) {
    this.prop = p;
  }
  getProp(): T {
    return this.prop;
  }
}
  • 也可以对泛型的范围进行约束
TypeScript 复制代码
interface Demo{
  length: number
}
function test<T extends Demo>(arg: T): number {
  return arg.length
}
// 类型number没有length属性,不能赋值给类型Demo的参数类型
test(10)
// 类型{name:string}的参数不能赋值给类型Demo的参数类型
test({name:'张三'})

// 这两个就是正确的
test('123')
test({name:'张三',length:18})

三、补充知识点

JS的缺点以及TS的弥补

JS 缺点

  1. 弱类型无静态校验:变量类型随意变更,报错只能运行时才暴露。
  2. 无类 / 接口 / 泛型等规范语法:原生 ES 类是语法糖,缺少面向对象约束。
  3. 大型项目维护难:无类型提示,多人协作易出现参数传错、属性不存在问题。
  4. 缺少枚举、命名空间:常量与类型管理混乱。

TS 弥补

  1. 增加静态类型,编译阶段提前拦截类型错误。
  2. 提供interface/abstract class/泛型/enum完善面向对象能力。
  3. 代码智能提示,降低大型项目维护成本。

TS的特点以及使用场景

TS 特点

  1. 超集 JS:兼容全部 JS 语法,可渐进式改造项目。
  2. 静态类型检查:编译期报错,规避线上隐患。
  3. 扩展语法:接口、泛型、枚举、抽象类、访问修饰符。
  4. 向下编译:可编译为任意版本 JS,兼容旧浏览器。

使用框架 / 项目

  • 前端:Vue3ReactAngularUniAppElement Plus
  • 后端:NestJS(Node 后端框架)
  • 大厂:微软、阿里、腾讯大部分中大型前端项目

TS的搭建以及如何运行TS代码

1. 环境搭建

  1. 安装 Node.js(自带 npm 包管理器)
  2. 终端执行:npm install -g typescript 全局安装 ts 编译器

2. 运行代码

  1. 新建demo.ts编写代码
  2. 编译:tsc demo.ts → 生成demo.js
  3. 执行:node demo.js

快捷工具:ts-node demo.ts,直接运行 ts 无需手动编译

相关推荐
IT策士1 小时前
第 46 篇 k8s之CI/CD 集成:GitOps 理念与 ArgoCD
前端·容器·kubernetes
Dalydai1 小时前
AI 辅助大屏开发:怎么让 AI 干活,但别让它干砸
前端
凌涘1 小时前
深入理解 JavaScript 执行机制:从执行上下文到调用栈全解析
前端·javascript
utmhikari1 小时前
【AI原生】用Vibe Coding写产品前端原型的一些经验
前端·ai·产品经理·web·web开发·ai-native·qoder
li星野1 小时前
从零搭建文件上传系统:FastAPI 后端 + Streamlit 前端
前端·状态模式·fastapi
用户938515635071 小时前
从模块化到 Prompt 工程:我用 Node.js + LLM 复刻了传统 NLP 的流程
javascript·人工智能·node.js
YAwu111 小时前
手写一个符合 Promise/A+ 规范的 Promise(附完整代码)
前端·javascript
bonechips1 小时前
用 Prompt 做 NLP:从零搭建一个情感分析与信息提取系统
javascript
暗不需求1 小时前
从路虎汽车小程序看微信小程序开发的最佳实践
前端·javascript·微信小程序