TypeScript学习笔记——TS类型/高级用法及实战优缺点

【TypeScript】 ts基本语法 JavaScript(也称为ECMAScript)诞生时是一种简单的浏览器脚本语言。当它被发明时,它被期望用于在网页中嵌入简短的代码片段。这些片段通常不超过几十行。因此,早期的 Web 浏览器执行此类代码的速度非常慢。但是,随着时间的推移,JS 变得越来越流行,并且 Web 开发者开始使用它来创造交互式体验。Web 浏览器开发者通过优化执行引擎(动态编译)和扩展可以完成的功能(添加API)来应对 JS 日益增加的使用量,这反过来又使 Web 开发者更多地使用 JS。 阅读详情

最近这两年,有很多人都在讨论 Typescript,无论是社区还是各种文章都能看出来,整体来说正面的信息是大于负面的,这篇文章就来整理一下我所了解的 Typescript。

TypeScript 类型

TypeScript有哪些类型

1、TypeScript 基本类型,也就是可以被直接使用的单一类型。

  • 数字
  • 字符串
  • 布尔类型
  • null
  • undefined
  • any
  • unknown
  • void
  • object
  • 枚举
  • never

2、复合类型,包含多个单一类型的类型。

  • 数组类型
  • 元组类型
  • 字面量类型
  • 接口类型

3、如果一个类型不能满足要求怎么办?

  • 可空类型,默认任何类型都可以被赋值成 null 或 undefined。
  • 联合类型,不确定类型是哪个,但能提供几种选择,如:type1 | type2。
  • 交叉类型,必须满足多个类型的组合,如:type1 & type2。

类型都在哪里使用

在变量中使用
在变量中使用时,直接在变量后面加上类型即可。

let a: number;
let b: string;
let c: null;
let d: undefined;
let e: boolean;
let obj: Ixxx = {
  a: 1,
  b: 2,
};
let fun: Iyyy = () => {};

在接口中使用
在接口中使用也比较简单,可以理解为组合多个单一类型。

interface IData {
  name: string;
  age: number;
  func: (s: string) => void;
}

在函数中使用
在函数中使用类型时,主要用于处理函数参数、函数返回值。

// 函数参数
function a(all: string) {}
// 函数返回值
function a(a: string): string {}
// 可选参数
function a(a: number, b?: number) {}

TypeScript 高级用法

Typescript 中的基本用法非常简单,有 js 基础的同学很快就能上手,接下来我们分析一下 Typescript 中更高级的用法,以完成更精密的类型检查。

类中的高级用法

在类中的高级用法主要有以下几点:

  • 继承
  • 存储器 get set
  • readonly 修饰符
  • df公有,私有,受保护的修饰符
  • 抽象类 abstract

继承和存储器和 ES6 里的功能是一致的,这里就不多说了,主要说一下类的修饰符和抽象类。

类中的修饰符是体现面向对象封装性的主要手段,类中的属性和方法在被不同修饰符修饰之后,就有了不同权限的划分,例如:

  • public 表示在当前类、子类、实例中都能访问。
  • protected 表示只能在当前类、子类中访问。
  • private 表示只能在当前类访问。
class Animal {
  // 公有,私有,受保护的修饰符
  protected AnimalName: string;
  readonly age: number;
  static type: string;
  private _age: number;
  // 属性存储器
  get age(): number {
    return this._age;
  }
  set age(age: number) {
    this._age = age;
  }
  run() {
    console.log("run", this.AnimalName, this.age);
  }
  constructor(theName: string) {
    this.AnimalName = theName;
  }
}
Animal.type = "2"; // 静态属性
const dog = new Animal("dog");
dog.age = 2; // 给 readonly 属性赋值会报错
dog.AnimalName; // 实例中访问 protected 报错
dog.run; // 正常

在类中的继承也十分简单,和 ES6 的语法是一样的。

class Cat extends Animal {
  dump() {
    console.log(this.AnimalName);
  }
}
let cat = new Cat("catname");

cat.AnimalName; // 受保护的对象,报错
cat.run; // 正常
cat.age = 2; // 正常

在面向对象中,有一个比较重要的概念就是抽象类,抽象类用于类的抽象,可以定义一些类的公共属性、公共方法,让继承的子类去实现,也可以自己实现。

抽象类有以下两个特点:

  • 抽象类不能直接实例化
  • 抽象类中的抽象属性和方法,必须被子类实现

tip 经典问题:抽象类的接口的区别:

  • 抽象类要被子类继承,接口要被类实现。
  • 在 ts 中使用 extends 去继承一个抽象类。
  • 在 ts 中使用 implements 去实现一个接口。
  • 接口只能做方法声明,抽象类中可以作方法声明,也可以做方法实现。
  • 抽象类是有规律的,抽离的是一个类别的公共部分,而接口只是对相同属性和方法的抽象,属性和方法可以无任何关联。

抽象类的用法如下:

abstract class Animal {
  abstract makeSound(): void;
  // 直接定义方法实例
  move(): void {
    console.log("roaming the earch...");
  }
}
class Cat extends Animal {
  makeSound() {} // 必须实现的抽象方法
  move() {
    console.log('move');
  }
}
new Cat3();

接口中的高级用法

接口中的高级用法主要有以下几点:

  • 继承
  • 可选属性
  • 只读属性
  • 索引类型:字符串和数字
  • 函数类型接口
  • 给类添加类型,构造函数类型

接口中除了可以定义常规属性之外,还可以定义可选属性、索引类型等。

interface Ia {
  a: string;
  b?: string; // 可选属性
  readonly c: number; // 只读属性
  [key: number]: string; // 索引类型
}
// 接口继承
interface Ib extends Ia {
  age: number;
}
let test1: Ia = {
  a: "",
  c: 2,
  age: 1,
};
test1.c = 2; // 报错,只读属性
const item0 = test1[0]; // 索引类型

接口中同时也支持定义函数类型、构造函数类型。

// 接口定义函数类型
interface SearchFunc {
  (source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function (x: string, y: string) {
  return false;
};
// 接口中编写类的构造函数类型检查
interface IClass {
  new (hour: number, minute: number);
}
let test2: IClass = class {
  constructor(x: number, y: number) {}
};

函数中的高级用法

函数重载
函数重载指的是一个函数可以根据不同的入参匹配对应的类型。

例如:案例中的 doSomeThing 在传一个参数的时候被提示为 number 类型,传两个参数的话,第一个参数就必须是 string 类型。

// 函数重载
function doSomeThing(x: string, y: number): string;
function doSomeThing(x: number): string;
function doSomeThing(x): any {}

let result = doSomeThing(0);
let result1 = doSomeThing("", 2);

This 类型
我们都知道,Javascript 中的 this 只有在运行的时候,才能够判断,所以对于 Typescript 来说是很难做静态判断的,对此 Typescript 给我们提供了手动绑定 this 类型,让我们能够在明确 this 的情况下,给到静态的类型提示。

其实在 Javascript 中的 this,就只有这五种情况:

  • 对象调用,指向调用的对象
  • 全局函数调用,指向 window 对象
  • call apply 调用,指向绑定的对象
  • dom.addEventListener 调用,指向 dom
  • 箭头函数中的 this ,指向绑定时的上下文
// 全局函数调用 - window
function doSomeThing() {
  return this;
}
const result2 = doSomeThing();

// 对象调用 - 对象
interface IObj {
  age: number;
  // 手动指定 this 类型
  doSomeThing(this: IObj): IObj;
  doSomeThing2(): Function;
}

const obj: IObj = {
  age: 12,
  doSomeThing: function () {
    return this;
  },
  doSomeThing2: () => {
    console.log(this);
  },
};
const result3 = obj.doSomeThing();
let globalDoSomeThing = obj.doSomeThing;
globalDoSomeThing(); // 这样会报错,因为我们只允许在对象中调用

// call apply 绑定对应的对象
function fn() {
  console.log(this);
}
fn.bind(document)();

// dom.addEventListener
document.body.addEventListener("click", function () {
  console.log(this); // body
});

泛型

泛型表示的是一个类型在定义时并不确定,需要在调用的时候才能确定的类型,主要包含以下几个知识点:

  • 泛型函数
  • 泛型类
  • 泛型约束 T extends XXX

我们试想一下,如果一个函数,把传入的参数直接输出,我们怎么去给它编写类型?传入的参数可以是任何类型,难道我们需要把每个类型都写一遍?

  • 使用函数重载,得把每个类型都写一遍,不适合。
  • 泛型,用一个类型占位 T 去代替,在使用时指定对应的类型即可。
// 使用泛型
function doSomeThing<T>(param: T): T {
  return param;
}

let y = doSomeThing(1);

// 泛型类
class MyClass<T> {
  log(msg: T) {
    return msg;
  }
}

let my = new MyClass<string>();
my.log("");

// 泛型约束,可以规定最终执行时,只能是哪些类型
function d2<T extends string | number>(param: T): T {
  return param;
}
let z = d2(true);

其实泛型本来很简单,但许多初学 Typescript 的同学觉得泛型很难,其实是因为泛型可以结合索引查询符 keyof、索引访问符 T[k] 等写出难以阅读的代码,我们来看一下。

// 以下四种方法,表达的含义是一致的,都是把对象中的某一个属性的 value 取出来,组成一个数组
function showKey1<K extends keyof T, T>(items: K[], obj: T): T[K][] {
  return items.map((item) => obj[item]);
}

function showKey2<K extends keyof T, T>(items: K[], obj: T): Array<T[K]> {
  return items.map((item) => obj[item]);
}

function showKey3<K extends keyof T, T>(
  items: K[],
  obj: { [K in keyof T]: any }
): T[K][] {
  return items.map((item) => obj[item]);
}

function showKey4<K extends keyof T, T>(
  items: K[],
  obj: { [K in keyof T]: any }
): Array<T[K]> {
  return items.map((item) => obj[item]);
}

let obj22 = showKey4<"age", { name: string; age: number }>(["age"], {
  name: "yhl",
  age: 12,
});

高级类型

TypeScript 中的高级类型包括:交叉类型、联合类型、字面量类型、索引类型、映射类型等,这里我们主要讨论一下

  • 联合类型
  • 映射类型

联合类型
联合类型是指一个对象可能是多个类型中的一个,如:let a :number | string 表示 a 要么是 number 类型,要么是 string 类型。

那么问题来了,我们怎么去确定运行时到底是什么类型?

答案是类型保护。类型保护是针对于联合类型,让我们能够通过逻辑判断,确定最终的类型,是来自联合类型中的哪个类型。

判断联合类型的方法很多:

  • typeof
  • instanceof
  • in
  • 字面量保护,=、!=、==、!=
  • 自定义类型保护,通过判断是否有某个属性等
// 自定义类型保护
function isFish(pet: Fish | Bird): pet is Fish {
  return (<Fish>pet).swim !== undefined;
}
if (isFish(pet)) {
  pet.swim();
} else {
  pet.fly();
}

映射类型
映射类型表示可以对某一个类型进行操作,产生出另一个符合我们要求的类型:

  • ReadOnly,将 T 中的类型都变为只读。
  • Partial,将 T 中的类型都变为可选。
  • Exclude,从 T 中剔除可以赋值给 U 的类型。
  • Extract,提取 T 中可以赋值给 U 的类型。
  • NonNullable,从 T 中剔除 null 和 undefined。
  • ReturnType,获取函数返回值类型。
  • InstanceType,获取构造函数类型的实例类型。

我们也可以编写自定义的映射类型。

//定义toPromise映射
type ToPromise<T> = { [K in keyof T]: Promise<T[K]> };
type NumberList = [number, number];
type PromiseCoordinate = ToPromise<NumberList>;
// [Promise<number>, Promise<number>]

TypeScript 总结

TypeScript 优点

1、静态类型检查,提早发现问题。

2、类型即文档,便于理解,协作。

3、类型推导,自动补全,提升开发效率。

4、出错时,可以大概率排除类型问题,缩短 bug 解决时间。

实战中的优点:

1、发现 es 规范中弃用的方法,如:Date.toGMTString。

2、避免了一些不友好的开发代码,如:动态给 obj 添加属性。

3、vue 使用变量,如果没有在 data 定义,会直接抛出问题。

TypeScript 缺点

1、短期增加开发成本。

2、部分库还没有写 types 文件。

3、不是完全的超集。

实战中的问题:

1、还有一些坑不好解决,axios 编写了拦截器之后,typescript 反映不到 response 中去。

TypeScript学习

对于Typescript的入门学习,我自己学习时看的是阿里大佬写的Typescript学习指南,一共分为16个类目去讲解Typescript ,包括文章中讲到的内容也在这份指南中,对于想TS详细学习的或想查漏补缺的小伙伴都很适合。

篇幅原因就不列举Typescript学习指南文档内容,完整版的【直接点击获取学习】,一起进入TS的世界。

结尾

假如你工作在一个大中型项目上面,typescript 对你应该是利大于弊。可以学!还能从另外一个方便了解静态类型语言是怎么玩的,看到别人的 Java 代码居然能有看得懂的部分了。 当然要学会根据自己的需求和项目的规模合理选用工具,如果你的应用就是一个简单的展示页面,加几个 UI 状态改变,就没有必要使用。

TS学习笔记六:高级类型/Symbols 本节介绍ts中的高级类型及Symbols相关内容,高级类型包括交叉类型、联合类型、类型保护、类型别名等内容,Symbols是ECMAScript 2015后的原生类型,像其他的基础类型number和string一样,通过Symbol构造函数创建,Symbol是不可改变且唯一的。 阅读详情

相关推荐

【TypeScript】TS接口类型(三)

我们经常说道的接口比如后端写了一个接口给前端调用,接口包括地址、参数、请求方式等等,参数规定了传参的类型。而在TS中的接口的定义是什么呢?顾名思义,它也是一种类型,和number、string、undefined等一样,约束使用者使用,主要是用来进一步定义对象中属性的类型。它是对行为模块的抽象,具体的行为是用类来实现。

编码世界 1万+

Typescript的复合类型

TS支持符合类型检查 这样可以让对象具备多类型数据结构

Cupido 692

【TypeScript】TS类型声明(二)

本人主要讲解TypeScript的基本数据结构,主要包括JS基本数据类型以及TS特有的数据类型。

编码世界 1万+

ts实战系列四:复合类型

一般用在表示函数不返回任何值或者返回undefined,因为函数不返回任何值的时候 === 返回undefined.(1). arguments是类数组对象,有length、下标[0],但是没有方法.any表示这个值可以是任何值,意味着不做任何类型检查,尽量避免使用any.在TS中,array一般指所有元素类型相同的值的集合.

wanmeijuhao的博客 510

【TypeScript】TS交叉类型&联合类型(四)

什么事交叉类型呢?简单来说就是通过`&`符号将多个类型进行合并成一个类型,然后用`type`来声明新生成的类型

编码世界 1万+

【TypeScript】TS类型守卫(六)

类型守卫主要是用来**判断未知类型是不是所需要的类型**。类型守卫主要包括四种方式:in,typeof, instanceof,自定义类型

编码世界 1万+

TS进阶实战

TS高级使用技巧 实现方式一: 实现方式二: ps:很明显方式二好些,工具函数可以复用,使用更加简便

weixin_44441196的博客 559

【TypeScript】TS条件类型(十)

条件类型允许根据一个或多个条件对类型进行推断,并且还能在在类型级别上进行复杂的逻辑运算和类型操作。

编码世界 6万+

【TS】常用类型概述

TS中常用的基本类型可以细分为两类:1. js已有类型,2.ts新增类型。

qq_45677671的博客 2380

【TypeScript】TS入门(一)

TS和JS的语言属于不同类型的语言,TS属于强类型语言,JS属于弱类型语言,强类型语言支持静态语言和动态语言,静态型语言支持动态语言,静态语言和动态语言有什么区别呢?

编码世界 1万+

git连接华为软件开发云

我用的是github客户端的git shell 连接。用git bash也可以github客户端下载地址:https://desktop.github.com/1.在华为软件开发云上创建代码仓库2.在本地创建密钥SSH密钥帮助文档公钥是代码托管服务(CodeHub)识别您的用户身份的一种认证方式,通过公钥,您可以将本地git项目与代码托管服务(CodeHub)建立联系, 然后您就可以很方便的将本地...

sigmeta的博客 2114

【TypeScript】TS入门到实战(详解)

熟悉ts如何使用;熟悉ts常用基本类型

qq_45796592的博客 1万+

【本体】Protege高效批量导入实例(Individuals)的自动化实践

本文详细介绍了在Protege中高效批量导入实例(Individuals)的自动化实践方法。通过分析Protege本体文件结构,提供Python脚本示例,帮助用户快速处理大规模数据导入,显著提升知识图谱构建效率。特别适合需要处理数千个实例的医疗、制药等领域应用。

weixin_30275415的博客 408

【TS】10 多个 TypeScript 高级用法总结

本文主要介绍 TypeScript 的高级用法,适用于对 TypeScript 已经有所了解或者已经实际用过一段时间的同学,分别从类型、运算符、操作符、泛型的角度来系统介绍常见的 Type...

pingan8787 1924

Autosar MCAL-S32K324 Fls配置-基于EB

Autosar MCAL Flash配置,基于S32K324,EB软件

赞的博客 1515

【ELK】最新版ELK日志搜集,过滤与展示,手把手教你搭建企业级ELK日志平台

ELFK是一套完整的日志集中处理方案。 E:ElasticSearck ES 分布式索引型非关系数据库 存储logstash输出的日志 全文检索引擎,保存的格式是json格式 L:logstash 基于java语言开发的,数据收集引擎。日志的收集,可以对数据进行过滤,分析,汇总,以标准格式输出 K:Kiabana 是es的可视化工具。对es存储的数据进行可视化展示,分析和检索。 F: FileBeat是一个轻量级日志采集器,Filebeat属于Beats家族的6个成员之一。

景天科技苑 7万+

【TypeScript】TS 看这一篇就够了

目标:能够理解TypeScript中有哪些数据类型可以将 TS 中的常用基础类型细分为两类:JS 已有类型原始类型,简单类型(复杂数据类型(数组,对象,函数等)TS 新增类型联合类型自定义类型(类型别名)接口元组字面量类型枚举void泛型是可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class 中需求:创建一个 id 函数,传入什么数据就返回该数据本身(也就是说,参数和返回值类型相同)

一个前端开发者 5894

《八》:玩家位置同步(玩家防碰撞)

在VR大空间体验中,由于玩家佩戴头显设备无法直接观察彼此位置,容易发生碰撞。因此,需要将玩家的实时位置信息绘制在虚拟空间中,实现位置可视化。通过获取头显的位置和旋转角度等数据,可以推算出玩家的移动状态和位置。使用可序列化的玩家结构体,通过UDP将玩家数据发送到服务器,服务器接收并反序列化数据后,同步所有玩家的最新信息至各客户端。客户端根据接收到的数据渲染虚拟人物模型,实现动态位置更新。这一过程涉及数据序列化、反序列化、网络通信和实时渲染等技术,确保玩家在虚拟空间中的位置同步和可视化。

unitygroup的博客 413

【TypeScript】TS入门到实战(详解:高级类型)

彻底理解typescript的语法并会用

qq_45796592的博客 2155

NLP高频面试题(一)——Transformer的基本结构、作用和代码实现

本文详细介绍了Transformer模型的基本结构和PyTorch代码实现过程。首先解析了Transformer的核心组成部分,包括嵌入层、多头自注意力机制、位置编码、前馈神经网络、编码器和解码器等模块,并通过清晰的代码示例逐步展示了如何在PyTorch中构建完整的Transformer模型。文末提供了一个可运行的简单示例,帮助读者快速理解并实践Transformer的核心原理与实现方法。

WeLearnNLP 1026

XCP实战系列介绍01-测量与标定底层逻辑介绍

XCP-测量与标定底层代码实现介绍,通过对相关API调用关系介绍加深开发人员对其功能的了解。

initiallizer的博客 1万+

TypeScript:熟练掌握TypeScript

TypeScript核心概念与优势摘要 TypeScript是JavaScript的超集,扩展了JS的静态类型系统,主要优势包括: 静态类型检查:编译阶段即可发现类型错误,避免运行时异常 增强开发体验:完善的代码提示和自动补全功能 面向对象支持:完整支持类、接口、泛型等特性 渐进式采用:兼容现有JS代码,可逐步迁移 框架友好:Vue3/Angular/React等主流框架深度集成 核心特性: 类型注解与接口定义 联合类型与类型别名 泛型编程支持 枚举与元组类型 类修饰符(public/private等) 适

snow的博客 9525

2xmax96717+max96724+agx orin驱动代码

说明:这里主要解决max96717的设备地址和sensor地址映射,vc0->vc1多颗max96717+max96724使用配置思路如下: 1、改变max96717的pipez stream id,然后max96724的pipe绑定使用相应的stream id 2、max96717默认是vc0,把vc0改写成vc1\vc2\vc3,然后max96724再重新映射vc输出

mantouyouyou的博客 113

【TS】TypeScript 类型声明文件.d.ts

TS 类型声明文件:用来为已存在的 JS 库提供类型信息。类型声明文件可以让我们不需要将JS重构为TS,就可以像用 TS 一样,有代码提示、类型保护等机制。 TS 中有两种文件类型:1 .ts 文件 2 .d.ts 文件 declare 关键字:用于类型声明,为其他地方(比如,.js 文件)已存在的变量声明类型,而不是创建一个新的变量。

zhonggee的博客 2877

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

对比ts-jest和Jest在处理TypeScript项目时的优缺点

摘要: ts-jest是Jest的TypeScript插件,通过TypeScript编译器实现代码转换与类型检查。对比Jest单独使用需配置Babel的方案,ts-jest优势在于原生支持TS所有特性、集成类型检查、调试友好,但编译速度较慢;Jest+Babel方案速度更快但无法类型检查。选择建议:重度依赖TS类型的项目优先用ts-jest,追求速度且仅用基础语法的项目可选Jest+Babel。多数TS项目推荐ts-jest以提前暴露类型错误。(149字)

前端技术的学习整理 758

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: 百度前端三面面试题全部公开,三面的最后一个问题令我窒息
下一篇: 101道经典JavaScript面试题总结(附答案,建议收藏)
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值