typeScript学习笔记总结(常用)

typeScript

ts:是js的超级!

为什么选择ts?

复制代码
ts的 静态类型检查 可以把运行时的错误前置
ts代码结构更清晰,更易维护

一、编译ts

css 复制代码
1.安装ts依赖包 npm/pnpm i typescript -g
2.编译
命令行编译	tsc 要编译的.ts文件
自动化编译	
tsc --init 后生成tsconfig.json配置文件,可根据需要调整配置
tsc --watch 事时检测文件夹下的所有文件

二、常用类型

类型 说明
string 字符串
number 数字
boolean 布尔
null
undefind 未定义
symbol 独一无二
bigint 大整数
any 任何值
unknown 未知类型
never 不能有值
void 通常用于函数返回值声明,能接受的返回值是 undefined
object 可以存储非原始类型的值
tuple 可以存储不同类型的数组,但是数量是固定的
enum 一组命名常量

type类型断言的方式:

typescript 复制代码
方法一:"尖括号"
let a:any = 'asd';
let b:number = (<string>a).length;
方法二:as语法
let a:any = 'asd';
let b:number = (a as string).length;
typescript 复制代码
对象声明形式
const obj = {a:string,b:number};

函数声明形式
let updata = (a:number,b:number)=>number

数组声明形式
const arr1 = Array<string>
const arr2 = array[string]

1.tuple(元组)

typescript 复制代码
let arr:[string,number];

2.enum(枚举)

typescript 复制代码
数字枚举
export enum FIELD_MAXCHARLENGTH_LIMIT {
  LIMIT = 1,
  NO_LIMIT = 0, 
}

字符串枚举
export const enum DiagramType {
  PROCESS = 'PROCESS', // 流程图
  ARCHITECTURE = 'ARCHITECTURE', // 架构图
  INTEGRATION = 'INTEGRATION', // 集成关系图
  ORGANIZATION = 'ORGANIZATION', // 组织图
  BPMN2 = 'BPMN2', // BPMN2.0图
  PROCESS_VIEW = 'PROCESS_VIEW', // 流程视图
}

3.type

typescript 复制代码
方式一
type num = number;
let price: num

方式二
type Status = number | string;
function printStatus(data:Status):void {
    console.log(data);
}

方式三
//面积
type Area = {
  height: number; //高
  width: number; //宽
};
type Address = {
  num: number; //楼号
  cell: number; //单元号
  room: string; //房间号
};

type House = Area & Address;
const house: House = {
  height: 100, //高
  width: 100, //宽
  num: 3, //楼号
  cell: 4, //单元号
  room: "702", //房间号
};

特殊情况
function updata():void {
    return undefined;
    return 100/'100'; // 会报错,因为void只允许返回为空,也就是最多能返回undefined
}

type IUpdata = () => void;
const f1: IUpdata = function () {
    return 66; // 不会报错
}
let x = f1();

原因
const src = [1,2,3];
const dst = [0];
src.forEach((el)=>dst.push(el));
为了让push等有返回值的方法能正常执行

4.属性修饰符

修饰符 含义 具体规则
public 公开的 可以被:类内部、子类、类外部访问
protected 受保护的 可以被:类内部、子类访问
private 私有的 可以被:类内部访问
readonly 只读属性 属性无法修改
typescript 复制代码
class Person {
    constructor(
    public name: string,
    protected age: number,
    private IDCard: string,
    public readonly sign: string
    ) { }
    getInfo() {
        console.log(this.name);	// 'tom'
        console.log(this.age); // 18
        console.log(this.IDCard); // '420xxxxx'
        console.log(this.sign); // '6515385'
    }
}

class Student extends Person {
    study(){
        console.log(this.name);	// 'tom'
        console.log(this.age); // 18
        console.log(this.IDCard); // 报错 private是私有的,只能被类内部访问
        console.log(this.sign); // '6515385'
    }
}

const p1 = new Person('tom',18,'420xxxxx','6515385')
p1.name	// 'tom'
p1.age	// 报错 protected只能被类内部、子类访问
p1.private // 报错 private是私有的,只能被类内部访问
p1.sign	// '6515385'
p1.sign = '123456789'	// 报错 readonly不允许修改

// 没有写修饰符默认是puublic!
属性的简写形式
typescript 复制代码
class Person {
    constructor(
    public name: string,
    public age: number
    ) { }
}

5.抽象类

概述 :抽象类是一种无法被实例化 的类,专门用来定义类的结构和行为 ,类中可以写抽象方法,也可以写具体实现 。抽象类主要用来为其派生类提供一个基础结构 ,要求其派生类必须实现 其中的抽象方法。 简记 :抽象类不能实例化 ,其意义是可以被继承 ,抽象类里可以有普通方法 、也可以有抽象方法

抽象类关键字abstract

何时使用抽象类

1.定义通用接口 :为一组相关的类定义通用的行为(方法或属性)时。 2.提供基础实现 :在抽象类中提供某些方法或为其提供基础实现,这样派生类就可以继承这些实现。 3.确保关键实现 :强制派生类实现一些关键行为。 4.共享代码和逻辑:当多个类需要共享部分代码时,抽象类可以避免代码重复

typescript 复制代码
abstract class Package {
  constructor(public weight: number) {}
  // 抽象⽅法:⽤来计算运费,不同类型包裹有不同的计算⽅式
  abstract calculate(): number;
  // 通⽤⽅法:打印包裹详情
  printPackage() {
    console.log(`包裹重量为: ${this.weight}kg,运费为: ${this.calculate()}元`);
  }
}

// StandardPackage 类继承了 Package ,实现了 calculate ⽅法:
class StandardPackage extends Package { // 标准包裹
  constructor(
    weight: number,
    public unitPrice: number // 每公⽄的固定费率
  ) {
    super(weight);  // 在子类构造函数中调用父类狗贼函数
  }
  // 实现抽象⽅法:计算运费
  calculate(): number {
    return this.weight * this.unitPrice;
  }
}
// 创建标准包裹实例
const s1 = new StandardPackage(10, 5);
s1.printPackage();

// ExpressPackage 类继承了 Package ,实现了 calculate ⽅法:
class ExpressPackage extends Package {	// 特快包裹
  constructor(
    weight: number,
    private unitPrice: number, // 每公⽄的固定费率(快速包裹更⾼)
    private additional: number // 超出10kg以后的附加费
  ) {
    super(weight);
  }
  // 实现抽象⽅法:计算运费
  calculate(): number {
    if (this.weight > 10) {
      // 超出10kg的部分,每公⽄多收additional对应的价格
      return 10 * this.unitPrice + (this.weight - 10) * this.additional;
    } else {
      return this.weight * this.unitPrice;
    }
  }
}
// 创建特快包裹实例
const e1 = new ExpressPackage(13, 8, 2);
e1.printPackage();

6.interface(接口)

interface只能定义格式,不能包含任何实现

何时使用interface

  1. 定义对象的格式: 描述数据模型、API 响应格式、配置对象........等等,是开发中⽤的最多的场景。
  2. 类的契约:规定⼀个类需要实现哪些属性和⽅法。
  3. 扩展已有接⼝:⼀般⽤于扩展第三⽅库的类型, 这种特性在⼤型项⽬中可能会⽤到。
定义类结构
typescript 复制代码
// PersonInterface接⼝,⽤与限制Person类的格式
interface PersonInterface {
  name: string;
  age: number;
  speak(n: number): void;
}
// 定义⼀个类 Person,用"implements"关联,实现 PersonInterface 接⼝
class Person implements PersonInterface {
  constructor(public name: string, public age: number) {}
  // 实现接⼝中的 speak ⽅法
  speak(n: number): void {
    for (let i = 0; i < n; i++) {
      // 打印出包含名字和年龄的问候语句
      console.log(`你好,我叫${this.name},我的年龄是${this.age}`);
    }
  }
}
// 创建⼀个 Person 类的实例 p1,传⼊名字 'tom' 和年龄 18
const p1 = new Person("tom", 18);
p1.speak(3);
定义对象结构
typescript 复制代码
interface UserInterface {
  name: string;
  readonly gender: string; // 只读属性
  age?: number; // 可选属性
  run: (n: number) => void;
}
const user: UserInterface = {
  name: "张三",
  gender: "男",
  age: 18,
  run(n) {
    console.log(`奔跑了${n}⽶`);
  },
};
定义函数结构
typescript 复制代码
interface CountInterface {
  (a: number, b: number): number;
}
const count: CountInterface = (x, y) => {
  return x + y;
};
接口之间的继承:使用 extends 进行关联
typescript 复制代码
interface PersonInterface {
  name: string; // 姓名
  age: number; // 年龄
}
interface StudentInterface extends PersonInterface {
  grade: string; // 年级
}
const stu: StudentInterface = {
  name: "张三",
  age: 25,
  grade: "⾼三",
};
接口自动合并(可重复定义)
typescript 复制代码
// PersonInterface接⼝
interface PersonInterface {
  // 属性声明
  name: string;
  age: number;
}
// 给PersonInterface接⼝添加新属性
interface PersonInterface {
  // ⽅法声明
  speak(): void;
}
// Person类实现PersonInterface
class Person implements PersonInterface {
  name: string;
  age: number;
  // 构造器
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  // ⽅法
  speak() {
    console.log("你好!我是⽼师:", this.name);
  }
}

7.interface 与 type 、interface 与 抽象类 的区别

7.1 interface 与 type
  • 相同点: interface 和 type 都可以⽤于定义对象结构,在定义对象结构时两者可以互换。
  • 不同点:
    • interface:更专注于定义对象和类的结构,⽀持继承、合并。
    • type:可以定义类型别名、联合类型、交叉类型,但不⽀持继承和⾃动合并。
typescript 复制代码
// interface 和 type 都可以定义对象结构
// 使⽤ interface 定义 Person 对象
interface PersonInterface {
  name: string;
  age: number;
  speak(): void;
}
// 使⽤ type 定义 Person 对象
type PersonType = {
  name: string;
  age: number;
  speak(): void;
};
// 使⽤PersonInterface
let person1: PersonInterface = {
name:'张三',
age:18,
speak(){
console.log(`我叫:${this.name},年龄:${this.age}`)
}
}
// 使⽤PersonType
let person2: PersonType = {
  name: "张三",
  age: 18,
  speak() {
    console.log(`我叫:${this.name},年龄:${this.age}`);
  },
};

// interface 可以继承、合并
interface PersonInterface {
  name: string; // 姓名
  age: number; // 年龄
}
interface PersonInterface {
  speak: () => void;
}
interface StudentInterface extends PersonInterface {
  grade: string; // 年级
}
const student: StudentInterface = {
  name: "李四",
  age: 18,
  grade: "⾼⼆",
  speak() {
    console.log(this.name, this.age, this.grade);
  },
};

// type 的交叉类型
// 使⽤ type 定义 Person 类型,并通过交叉类型实现属性的合并
type PersonType = {
  name: string; // 姓名
  age: number; // 年龄
} & {
  speak: () => void;
};
// 使⽤ type 定义 Student 类型,并通过交叉类型继承 PersonType
type StudentType = PersonType & {
  grade: string; // 年级
};
const student: StudentType = {
  name: "李四",
  age: 18,
  grade: "⾼⼆",
  speak() {
    console.log(this.name, this.age, this.grade);
  },
};
7.2 interface 与 抽象类
  • 相同点:都能定义⼀个类的格式(定义类应遵循的契约)
  • 不相同:
    • 接⼝:只能描述结构,不能有任何实现代码,⼀个类可以实现多个接口。
    • 抽象类:既可以包含抽象⽅法,也可以包含具体⽅法,⼀个类只能继承⼀个抽象类。
typescript 复制代码
// ⼀个类可以实现多个接⼝
// FlyInterface 接⼝
interface FlyInterface {
  fly(): void;
}
// 定义 SwimInterface 接⼝
interface SwimInterface {
  swim(): void;
}
// Duck 类实现了 FlyInterface 和 SwimInterface 两个接⼝
class Duck implements FlyInterface, SwimInterface {
  fly(): void {
    console.log("鸭⼦可以⻜");
  }
  swim(): void {
    console.log("鸭⼦可以游泳");
  }
}
// 创建⼀个 Duck 实例
const duck = new Duck();
duck.fly(); // 输出: 鸭⼦可以⻜
duck.swim(); // 输出: 鸭⼦可以游泳

三、泛型

泛型允许我们在定义函数、类或接⼝时,使⽤类型参数来表示未指定的类型,这些参数在具体使⽤时,才被指定具体的类型,泛型能让同⼀段代码适⽤于多种类型,同时仍然保持类型的安全性。

typescript 复制代码
// 泛型函数
function logData<T>(data: T): T {
  console.log(data);
  return data;
}
logData<number>(100);
logData<string>("hello");

// 泛型可以有多个
function logData<T, U>(data1: T, data2: U): T | U {
  console.log(data1, data2);
  return Date.now() % 2 ? data1 : data2;
}
logData<number, string>(100, "hello");
logData<string, boolean>("ok", false);

// 泛型接⼝
interface PersonInterface<T> {
  name: string;
  age: number;
  extraInfo: T;
}
let p1: PersonInterface<string>;
let p2: PersonInterface<number>;
p1 = { name: "张三", age: 18, extraInfo: "⼀个好⼈" };
p2 = { name: "李四", age: 18, extraInfo: 250 };

// 泛型约束
interface LengthInterface {
  length: number;
}
// 约束规则是:传⼊的类型T必须具有 length 属性
function logPerson<T extends LengthInterface>(data: T): void {
  console.log(data.length);
}
logPerson<string>("hello");
// 报错:因为number不具备length属性
// logPerson<number>(100)

// 泛型类
class Person<T> {
  constructor(public name: string, public age: number, public extraInfo: T) {}
  speak() {
    console.log(`我叫${this.name}今年${this.age}岁了`);
    console.log(this.extraInfo);
  }
}
// 测试代码1
const p1 = new Person<number>("tom", 30, 250);
// 测试代码2
type JobInfo = {
  title: string;
  company: string;
};
const p2 = new Person<JobInfo>("tom", 30, {
  title: "研发总监",
  company: "发发发科技公司",
});

四、类型声明文件

类型声明⽂件是 TypeScript 中的⼀种特殊⽂件,通常以 .d.ts 作为扩展名。它的主要作⽤是为现有的 JavaScript 代码提供类型信息,使得 TypeScript 能够在使⽤这些 JavaScript 库或模块时进⾏类型检查和提示。

javascript 复制代码
// demo.js 中写了两个方法add、mul
export function add(a, b) {
  return a + b;
}
export function mul(a, b) {
  return a * b;
}

// 在index.ts中使用了这两个方法,会报错 说add、mul都是any类型
import { add, mul } from "./demo.js";
const x = add(2, 3); // x 类型为 number
const y = mul(4, 5); // y 类型为 number
console.log(x, y);

// 需要通过 demo.d.ts 文件对这个js文件类型进行声明(declare 声明关键字)
import { add, mul } from "./demo.js";
const x = add(2, 3); // x 类型为 number
const y = mul(4, 5); // y 类型为 number
console.log(x, y);
相关推荐
之恒君3 小时前
TypeScript(tsconfig.json - references)
typescript
之恒君21 小时前
typescript(tsconfig.json - esModuleInterop)
前端·typescript
guangzan1 天前
VS Code 操作 “Delete unused imports” 时,不删除 React 导入
vscode·typescript·eslint
华仔啊1 天前
别再写 TypeScript enum了!新枚举方式让 bundle 瞬间小20%
javascript·typescript
子兮曰1 天前
🚀彻底掌握异步编程:async/await + Generator 深度解析与20个实战案例
前端·javascript·typescript
知否技术1 天前
别再踩坑了!这份 Vue3+TypeScript 项目教程,赶紧收藏!
前端·typescript
@AfeiyuO2 天前
分类别柱状图(Vue3)
typescript·vue·echarts
一只小风华~2 天前
Vue:条件渲染 (Conditional Rendering)
前端·javascript·vue.js·typescript·前端框架
烛阴2 天前
【TS 设计模式完全指南】用适配器模式优雅地“兼容”一切
javascript·设计模式·typescript