TypeScript学习笔记 其二

TypeScript学习笔记 其二

学习React时发现TS是一个绕不过去的坎儿,所以打算趁着春节有时间顺便系统的学习一下TS😄。。

第二篇整理了TypeScrip相关的数据类型,并根据它们不同的特性写了demo。

该系列目录:

第一篇:TypeScript学习笔记 其一
第二篇:TypeScript学习笔记 其二
....待续....

数据类型

在ES6中有六种基本数据类型:Boolean、Number、String、Symbol、undefined、null;三种引用类型:Array、Function、Object。
TypeScript在ES6的基础上又新增了几种类型:void、any、never、元组、枚举

ES6的数据类型 TypeScript中和ES6一致的数据类型 TypeScript中新增的数据类型
Boolean Boolean void
Number Number any
String String never
Symbol Symbol 元组
undefined undefined 枚举
null null
Array Array
Function Function
Object Object

各数据类型的定义

首先介绍个概念:类型注解,作用相当于强类型语言的类型声明,可以对声明类型的变量或函数起到类型约束作用;语法为(变量/函数) : type

在上节的index.ts中我们写了一行代码:let hello : string = "Hello TypeScript",就是声明变量hello的类型为string。

以下示例均可在TypeScript国内官网的在线运行测试网页中测试

  1. Boolean: 表示逻辑值:true 和 false。例:let bool: boolean = true

  2. Number: 双精度 64 位浮点值。它可以用来表示整数和分数。例:let decLiteral: number = 666

  3. String: 一个字符系列,使用单引号(')或双引号(")来表示字符串类型。反引号(`)来定义多行文本和内嵌表达式。例:let myName: string = "AzumaTokaku"

  4. undefined和null: undefined用于初始化变量为一个未定义的值;null表示对象值缺失。例:let un: undefined = undefined; let nu: null = null;值得注意的是,ts中默认严格校验类型约束,如这种情况会报错Type 'null' is not assignable to type 'number'.Type 'undefined ' is not assignable to type 'number'.,只有在tsconfig.json中设置strictNullChecks为false,才会正常编译。如果不设置strictNullChecks为false,也可以声明num为多个类型:let num: number | undefined | null = 123,这样也可以通过类型约束检查。

    let num: number = 123
    let un: undefined = undefined
    let nu: null = null
    num = undefined
    num = null
    

ts中默认严格校验类型约束

  1. Symbol: 表示独一无二的值,常用来定义对象的唯一属性名。在实例中,s1和s2虽然创建过程一模一样,但是并不相等。不通过Symbol.for()方法创建的变量无法通过Symbol.keyFor()方法取值。Symbol.for() 类似单例模式,会在全局中搜索被登记的Symbol中是否有该参数作为名称的Symbol值,如果有即返回该Symbol值,若没有则新建并返回一个以该参数为名称的Symbol值,并登记在全局环境中供搜索。Symbol.keyFor()只能返回一个已登记的Symbol类型值的key。

    let s1: symbol = Symbol("kk")
    console.log(Symbol.keyFor(s1))
    let s2: symbol = Symbol("kk")
    console.log(s1 === s2)
    s1 = Symbol.for("Yannis");
    console.log(s1)
    console.log(Symbol.keyFor(s1))
    

Symbol

  1. void: 用于标识方法返回值的类型,表示该方法没有返回值。例:let noReturn = (): void=> {return 1 + 1}; 如果return值,会报Type 'number' is not assignable to type 'void'.。由于undefined在js中并不是保留字有可能会被赋值替换,所以有时也会用void 0表示undefined。

void

  1. any: 类型声明为any的变量可以赋予任意类型的值。一般不使用,用了any就没有使用TypeScript进行类型约束的意义。
  2. never: never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型,也就没有任何类型可以赋值给never类型(除了never本身之外), 即使 any也不可以赋值给never。在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)。
let x: never;
let y: number;

// 运行错误,数字类型不能转为 never 类型
x = 123;

// 运行正确,never 类型可以赋值给 never类型
x = (()=>{ throw new Error('exception')})();

// 运行正确,never 类型可以赋值给 数字类型
y = (()=>{ throw new Error('exception')})();

// 返回值为 never 的函数可以是抛出异常的情况
function error(message: string): never {
	throw new Error(message);
}

// 返回值为 never 的函数可以是无法被执行到的终止点的情况
function loop(): never {
	while (true) {}
}

never

  1. 数组: 使用单独的变量名来存储一系列的值。
// 两种声明方式
let arr1: number[] = [1, 2, 3]
let arr2: Array<number> = [1, 2, 3]
// 联合类型声明,数组的值既可以是number类型也可以是string类型
let arr3: Array<number | string> = [1, 2, 3, '4']
  1. 元组: 表示一个已知元素数量和类型的数组,各元素的类型不必相同。
// 元组
let tuple: [number, string] = [0, '1']
// 元组的越界问题,可以使用push方法往元组中插入新元素
tuple.push(2)
// 打印结果[0, "1", 2],会发现元素已经插入进去了
console.log(tuple)
// 但是元组不允许访问越界插入的新元素
tuple[2]

元组

  1. 函数: 函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义行为的地方。

    // add函数的x,y参数声明为number类型,返回值也声明为number类型;不过通常函数的返回值可以省略,TypeScript会自动推断类型,这叫做“按上下文归类”,是类型推论的一种。
    let add = (x: number, y: number) : number => x + y
    // let add = (x: number, y: number)  => x + y
    
    // 定义一个compute函数类型,但是没有具体实现
    let compute: (x: number, y: number) => number
    // 实现compute函数类型,在实现过程中可以不指定具体的类型
    compute = (a, b) => a + b
    
  2. 对象: object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。

    let obj1: object = { x: 1, y: 2 }
    // 报错:Property 'x' does not exist on type 'object'.
    obj1.x = 3
    
    let obj2: { x: number, y: number } = { x: 1, y: 2 }
    // 正常编译
    obj2.x = 3
    

枚举

枚举: 一组有名字的常量集合。枚举类型被编译成一个对象,它包含了正向映射( name -> value)和反向映射( value -> name)。 引用枚举成员总会生成为对属性访问并且永远也不会内联代码(字符串枚举除外)。

// 数字枚举,默认从0开始,即Role.Reporter的值为0,后面的值依次递增
	enum Role {
		Reporter,
		Developer,
		Maintainer,
		Owner,
		Guest
	}
	//Role.Reporter值为0
	console.log("数字枚举:" + Role.Reporter);
	//数字枚举的反向映射
	let reporter = Role.Reporter;
	console.log("数字枚举的反向映射:" + Role[reporter]);
	
	// 数字枚举,可设置初始值,即Role.Reporter的值为1,后面的值依次递增
	enum Role {
				Reporter = 1,
				Developer,
				Maintainer,
				Owner,
				Guest
	}
	//Role.Developer值为2		
	console.log("设置初始值的数字枚举:" + Role.Developer);
	
	// 字符串枚举
	enum Message {
		Success = '恭喜你,成功了',
		Fail = '抱歉,失败了'
	}
	console.log("字符串枚举:" + Message.Success);

	// 异构枚举,数字枚举和字符串枚举同时使用,一般不推荐这样做,容易混淆
	enum Answer {
		N,
		Y = 'Yes'
	}
	// Answer.N值为0
	console.log("异构枚举:" + Answer.N);
	// Answer.Y值为Yes
	console.log("异构枚举:" + Answer.Y);

	// 常量枚举,用const声明的枚举就是常量枚举;常量枚举在编译阶段会被移除,常量枚举不允许包含需要被计算的枚举成员。当不需要一个对象,只需要对象的值时,可以使用常量枚举;这样可减少编译阶段的代码
	const enum Month {
		Jan,
		Feb,
		Mar
	}
	// 编译后枚举会被直接替换成常量,运行时的代码会变得简洁
	let month = [Month.Jan, Month.Feb, Month.Mar]

枚举

枚举成员的性质:

  • 枚举成员的值为只读类型,定义后不可修改。
  • 枚举成员分为两种:常量枚举成员(const member)和需要被计算的枚举成员(computed member
  • 常量枚举成员包括三种情况:没有初始值的枚举成员、对已有枚举成员的引用、常量表达式;常量枚举成员会在编译的时候计算出结果,然后以常量的形式出现在运行环境。
  • 需要被计算的枚举成员是一些非常量的表达式, 需要被计算的枚举成员不会在编译的阶段计算,会被保留到程序的运行阶段才进行计算。
  • 在需要被计算的枚举成员后面的枚举成员一定要赋初始值
enum Char {
   	// 常量枚举成员 const member
   	a,
   	b = Char.a,
   	c = 1 + 3,
   	// 需要被计算的枚举成员 computed member
   	d = Math.random(),
   	e = '123'.length
   }

常量枚举成员和需要被计算的枚举成员的区别

枚举类型: 在某些情况下,枚举和枚举成员都可以作为类型存在;枚举类型可以分为三种情况:

  • 枚举成员没有初始值
  • 所有枚举成员为数字类型
  • 所有枚举成员为字符串类型
// 枚举类型三种情况:
   // 枚举成员没有初始值
   enum E { a, b }
   // 所有枚举成员为数字类型
   enum F { a = 0, b = 1 }
   // 所有枚举成员为字符串类型
   enum G { a = 'apple', b = 'banana' }

   // 可以把任意的数字赋值声明为E、F枚举类型的变量
   let e: E = 3
   let f: F = 3
   // 枚举类型不同的变量不可进行比较,会报错
   console.log(e === f)

   // 枚举成员也可做为类型声明给变量 
   let e1: E.a = 3
   let e2: E.b = 3
   let e3: E.a = 3
   // 枚举类型不同的变量不可进行比较,会报错
   console.log(e1 === e2)
   // e1和e3枚举类型相同,可进行比较
   console.log(e1 === e3)

   // 声明为字符串枚举类型的变量,值只能为枚举成员的值
   let g1: G = G.a
   // 声明为字符串枚举成员类型的变量,值只能为它自己的值
   let g2: G.a = G.a

枚举类型不同的变量不可进行比较


标题:TypeScript学习笔记 其二
作者:AzumaTokaku
地址:https://www.azumatokaku.cc/articles/2022/01/26/1643201667912.html

    评论
    0 评论
avatar

取消