首页 > 其他分享 >第二篇 TypeScript 【 typeScript 断言 + typeScript 类型守卫 + typeScript 联合类型、可辨识联合和类型别名 + typeScript 交叉类型

第二篇 TypeScript 【 typeScript 断言 + typeScript 类型守卫 + typeScript 联合类型、可辨识联合和类型别名 + typeScript 交叉类型

时间:2023-03-28 15:57:08浏览次数:40  
标签:TypeScript string number 接口 interface typeScript 类型

typeScript 断言

1、有时候你会遇到这样的情况,你会比 TypeScript 更了解某个值的详细信息,通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型

2、通过 类型断言 这种方式可以告诉编译器,“相信我,我知道自己在干什么”

3、类型断言 好比其他语言里的类型转换,但是不进行特殊的数据检查和解构

4、类型断言 没有运行时的影响,只是在编译阶段起作用

5、类型断言有两种形式

   1、“尖括号” 语法
   
   2、as 语法
“尖括号” 语法
let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;
as 语法
let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

typeScript 类型守卫 【 类型保护 】

1、类型保护 是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内

2、类型保护 可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值

3、类型保护 与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值

4、目前主要有 四种 方式来实现 类型保护

   1、in 关键字
   
   2、typeof 关键字
   
   3、instanceof 关键字
   
   4、自定义类型保护的类型谓词
in 关键字
interface Admin {
  name: string;
  privileges: string[];
}

interface Employee {
  name: string;
  startDate: Date;
}

type UnknownEmployee = Employee | Admin;

function printEmployeeInformation(emp: UnknownEmployee) {
  console.log("Name: " + emp.name);
  if ("privileges" in emp) {
    console.log("Privileges: " + emp.privileges);
  }
  if ("startDate" in emp) {
    console.log("Start Date: " + emp.startDate);
  }
}
typeof 关键字
function padLeft(value: string, padding: string | number) {
  if (typeof padding === "number") {
      return Array(padding + 1).join(" ") + value;
  }
  if (typeof padding === "string") {
      return padding + value;
  }
  throw new Error(`Expected string or number, got '${padding}'.`);
}

1、typeof 类型保护只支持两种形式:typeof v === "typename" 和 typeof v !== typename

2、"typename" 必须是 "number", "string", "boolean" 或 "symbol"

3、TypeScript 并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护
instanceof 关键字
interface Padder {
  getPaddingString(): string;
}

class SpaceRepeatingPadder implements Padder {
  constructor(private numSpaces: number) {}
  getPaddingString() {
    return Array(this.numSpaces + 1).join(" ");
  }
}

class StringPadder implements Padder {
  constructor(private value: string) {}
  getPaddingString() {
    return this.value;
  }
}

let padder: Padder = new SpaceRepeatingPadder(6);

if (padder instanceof SpaceRepeatingPadder) {
  // padder的类型收窄为 'SpaceRepeatingPadder'
}
补充 TypeScript 中 implements 与 extends 的区别
1、implements

   实现,一个新的类,从父类或者接口实现所有的属性和方法,同时可以重写属性和方法,包含一些新的功能

2、extends

   继承,一个新的接口或者类,从父类或者接口继承所有的属性和方法,不可以重写属性,但可以重写方法
   

interface IPerson {
  age: number;
  name: string;
}

interface IPeoPle extends IPerson {
  sex: string;
}

class User implements IPerson {
  age: number;
  name: string;
}
interface IRoles extends User{

}
class Roles extends User{
  
}

注意

   1、接口不能实现接口或者类,所以实现只能用于类身上,即类可以实现接口或类
   
   2、接口可以继承接口或类
   
   3、类不可以继承接口,类只能继承类
   
   4、可多继承或者多实现
自定义类型保护的类型谓词
function isNumber(x: any): x is number {
  return typeof x === "number";
}

function isString(x: any): x is string {
  return typeof x === "string";
}

typeScript 联合类型和类型别名

联合类型
1、联合类型通常与 null 或 undefined 一起使用

const sayHello = (name: string | undefined) => {
  /* ... */
};

这里 name 的类型是 string | undefined 意味着可以将 string 或 undefined 的值传递给sayHello 函数

sayHello("Semlinker");
sayHello(undefined);

2、通过这个示例,可以凭直觉知道类型 A 和类型 B 联合后的类型是同时接受 A 和 B 值的类型
可辨识联合
1、TypeScript 可辨识联合【 Discriminated Unions 】类型,也称为代数数据类型或标签联合类型

2、TypeScript 可辨识联合 包含 3 个要点

   1、可辨识
   
   2、联合类型
   
   3、类型守卫
可辨识
可辨识要求联合类型中的每个元素都含有一个单例类型属性

enum CarTransmission {
  Automatic = 200,
  Manual = 300
}

interface Motorcycle {
  vType: "motorcycle"; // discriminant
  make: number; // year
}

interface Car {
  vType: "car"; // discriminant
  transmission: CarTransmission
}

interface Truck {
  vType: "truck"; // discriminant
  capacity: number; // in tons
}

在上述代码中,我们分别定义了 Motorcycle、 Car 和 Truck 三个接口

在这些接口中都包含一个 vType 属性,该属性被称为可辨识的属性,而其它的属性只跟特性的接口相关
联合类型
基于前面定义了三个接口,我们可以创建一个 Vehicle 联合类型

type Vehicle = Motorcycle | Car | Truck;

现在我们就可以开始使用 Vehicle 联合类型,对于 Vehicle 类型的变量,它可以表示不同类型的车辆
类型守卫
下面我们来定义一个 evaluatePrice 方法,该方法用于根据车辆的类型、容量和评估因子来计算价格,具体实现如下

const EVALUATION_FACTOR = Math.PI; 
function evaluatePrice(vehicle: Vehicle) {
  return vehicle.capacity * EVALUATION_FACTOR;
}

const myTruck: Truck = { vType: "truck", capacity: 9.5 };
evaluatePrice(myTruck);

对于以上代码,TypeScript 编译器将会提示以下错误信息

Property 'capacity' does not exist on type 'Vehicle'.
Property 'capacity' does not exist on type 'Motorcycle'

原因是在 Motorcycle 接口中,并不存在 capacity 属性,而对于 Car 接口来说,它也不存在 capacity 属性

这时,我们可以使用类型守卫。下面我们来重构一下前面定义的 evaluatePrice 方法,重构后的代码如下

function evaluatePrice(vehicle: Vehicle) {
  switch(vehicle.vType) {
    case "car":
      return vehicle.transmission * EVALUATION_FACTOR;
    case "truck":
      return vehicle.capacity * EVALUATION_FACTOR;
    case "motorcycle":
      return vehicle.make * EVALUATION_FACTOR;
  }
}

我们使用 switch 和 case 运算符来实现类型守卫,从而确保在 evaluatePrice 方法中,我们可以安全地访问 vehicle 对象中的所包含的属性,来正确的计算该车辆类型所对应的价格
类型别名
类型别名用来给一个类型起个新名字

type Message = string | string[];

let greet = (message: Message) => {
  // ...
};

typeScript 交叉类型 【 type C = A & B 】

1、TypeScript 交叉类型是将多个类型合并为一个类型

2、这可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性

interface IPerson {
  id: string;
  age: number;
}

interface IWorker {
  companyId: string;
}

type IStaff = IPerson & IWorker;

const staff: IStaff = {
  id: 'E1006',
  age: 33,
  companyId: 'EFT'
};

console.dir(staff)

在上面示例中,首先为 IPerson 和 IWorker 类型定义了不同的成员,然后通过 & 运算符定义了 IStaff 交叉类型,所以该类型同时拥有 IPerson 和 IWorker 这两种类型的成员

标签:TypeScript,string,number,接口,interface,typeScript,类型
From: https://www.cnblogs.com/caix-1987/p/17265514.html

相关文章

  • 第六篇 TypeScript 【 typeScript 编译上下文 tsconfig.json 】
    typeScript编译上下文tsconfig.json的作用1、用于标识TypeScript项目的根路径2、用于配置TypeScript编译器3、用于指定编译的文件tsconfig.json重要字段1......
  • 第五篇 TypeScript 【 typeScript 泛型 + typeScript 装饰器 】
    typeScript泛型1、软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统......
  • 第六篇 引用类型 - 函数 - Function
    函数—javascript的第一等公民函数的多变来源于参数的灵活多变和返回值的多变普通函数—如果参数是一般的数据类型或一般对象,这样的函数就是通函数高级函数—如......
  • 第七篇 基本包装类型-字符串类型 - String、Number、Boolean
    基本包装类型基本包装类型是特殊的引用类型ECMAScript提供了三种基本包装类型NumberStringBoolean每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装......
  • 标识符、基本数据类型、变量、
    1.标识符变量名、常量名、类名、对象名、方法名,凡事自己子程序中定义使用的文字,就是标识符命名规范以任何英文字母,下划线_开头的开始,美元符号$跟随着任何字母、数......
  • QT中将float数转换为QString类型
    概述直接上代码,下面是示例:示例一floatup=23.45;QStringstr=QString::number(up,'f',2);12示例二floatup=23.45;QStringstr=QString::asprintf(......
  • C#中测试普通方法和对象类型以及泛型所需要的时间
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceMyGeneric{publicclassCo......
  • MyBatis中Java类型与别名的对应关系表
    常见Java类型有许多内置的类型别名。注意,它们都是不区分大小写的,由于重载名称而对原语进行特殊处理。下面给出对应关系表:别名Java类型_bytebyte_longlong_......
  • 第一篇 javascript 数据类型
    1、数据类型基础数据类型(7种)1、String2、Number3、Boolean4、null5、undefined6、Symbol7、bigInit引用数据类型(Object)1、Object2、Array3、Fun......
  • C#类型后加问号?
    C#可空类型(Nullable)说明_w3cschool细说Nullable<T>类型-Sweet-Tang-博客园(cnblogs.com)值类型变量不能null,加问号就是可以为空。可空类型,可以给值类型赋值null。......