TypeScript 能够看作是 JavaScript 的超集,不仅蕴含了 JavaScript 的所有内容,还拓展了语法、规定了类型束缚,使得咱们能够编写更洁净、残缺的代码。

类型注解

TypeScript提供了很多数据类型,通过类型对变量进行限度,称之为类型注解,应用类型注解后,就不可能随便变更变量的类型。

以下代码定义了一个字符串类型的变量,如果把它更改为数字类型时,代码编译阶段就会间接报错,提醒 "Type 'number' is not assignable to type 'string'"。

这样保障变量的数据类型是固定的,那么它所能应用的办法也是确定的,不会呈现变量原本是字符串,调用了 toUpperCase办法,起初在未测试到的某场景无心中把它改为数字类型后,调用 toUpperCase 间接报错的状况。

类型推导

当变量没有写数据类型时,ts外部会进行"类型推导",通过上下文赋值语句判断出该变量的数据类型,所以在类型注解较为简单时且其能精确主动推导出类型时,不写类型注解对代码品质也没有影响。

TS和JS共有的数据类型

TypeScript蕴含了JavaScript所领有的数据类型,string、number、symbol、array、boolean、undefined、null、object。

其中,array 在定义的时候须要加上数组中的每一个数据的类型,是字符串、数字还是对象,这就使得数组中不能够写多种数据类型,如果有须要写多种数据类型的状况,能够间接不加类型注解,会主动进行【类型推导】。

let str: string = "string";let num: number = 0;let sym: symbol = Symbol("sym");let arr1: string[] = ['alice', 'kiki', 'heidi']let arr2: object[] = [{ name: 'alice'}]let arr3: number[] = [1, 2, 3]let flag: boolean = false;let und: undefined = undefined;let nu: null = null;let user = { name: "alice" };

下面的对象user也是没有加类型注解的,因为如果定义为 object 类型,无奈获取和批改user对象上的属性。

这是因为user是object类型,但object类型上没有name属性,所以编译阶段会间接报错,所以对于对象能够不加类型注解,让其主动进行类型推导。

TS独有的数据类型

此外TypeScirpt还减少了很多JavaScript没有的数据类型

any

any是一个 "万金油" 的数据类型,示意 "任意" 数据类型,当变量的类型不确定且有可能发生变化时,能够定义为 any,此时变量的数据类型能够被随便更改,这其实会带来一些安全隐患。

比方上面的代码,将字符串当作函数应用,undefined应用数字的办法。因为是any类型,类型有可能被改成字符串、数字、布尔值,所以这样的代码不会被ts检测出问题,但在运行时必定是会报错的。

let message: any = "message";message();message = 0;message = undefined;message.toFixed();

unknown

当一个变量的类型临时不确定时,能够应用unknown用来限度其类型。

let flag = truelet result: unknown;if (flag) {  result = 'Hello World'} else {  result = 888}

它和any有些像,但区别在于unknown是不能被赋值给除了any和unknown类型的变量,这样使得unknown的值不能被乱用到其它中央。

void

当函数没有返回值时,实际上返回的就是 undefined,void 通常用来示意函数返回值为 undefined 或者 null。

以下模式都是能够的

function add(): void {}function sub(): void {  return undefined}function mul(): void {  return null}

当存在返回值时,编译是会报错的。

never

never 示意永远不会存在的类型,如果函数为死循环或者抛出异样时能够应用。

function foo(): never {  while (true) {}}function catchError(): never {  throw new Error("error");}

当咱们封装工具函数时,开始规定的函数入参为 string 类型,但可能后续在其它人开发过程中,减少了 number 类型,为了防止保护时遗记对该类型数据进行解决,能够把入参赋值给 never 类型的变量,使得编译不通过来避免开发者逻辑疏漏。

tuple

tuple 意思是元组,和数组比拟类似,但元组和数组还是存在以下区别。

  • 数组中元素数据类型倡议是统一的,当数据类型不统一时思考放到元组或者对象。
  • 元组中每个元素都有本人的个性,能够通过索引值获取。
// 数组const array: string[] = ["alice", "kiki"];// 元组const tuple: [string, number] = ["alice", 20];

函数参数和返回值

申明函数时,在函数的每个参数后增加类型注解,以申明函数承受的参数类型,限度参数类型、参数个数。

在函数列表前面定义的类型注解,用于限度函数返回值类型的。

// 限度参入类型function foo(message: string, no: number) {}// 限度返回值function baz(message: string): string {  return "string";}

当入参类型/个数没有达到注解要求时,编译会标红以揭示。

对象类型、可选类型、联结类型 也都是能够用于规定函数入参的。

  • 对象类型,定义对象中每个参数的数据类型
  • 可选类型,用 ?示意,意味着该参数是非必传的,必须写在必选类型前面
  • 联结类型,用 | 示意,A | B 意味着入参类型是A和B中的任意一个
function getPoint(point: { x: number; y: number; z?: number }) {}getPoint({ x: 10, y: 20 });getPoint({ x: 10, y: 20, z: 30 });function printId(id: string | number) {}printId(1);printId("alice");function foo(message?: string) {}foo("message");foo();

当须要规定的类型比拟长时,能够通过 type 关键字来定义类型别名

同时参数类型为【可选类型】能够了解该参数类型与 undefined 的【联结类型】,以下两个参数的入参实质上是一样的

function foo(message?: string) {}foo("message");foo();function baz(message: string | undefined) {}baz("message");baz(undefined);

类型断言

有时候TypeScirpt获取到的类型是比拟宽泛的,这个时候能够应用类型断言,通过关键字 as 定义具体数据类型。

比方以下定义了两个类,Student 继承自 Person 类,且领有本人的 studying 办法,定义sayHello办法,要求入参类型为Person,此时创立Student的实例对象student,并调用sayHello办法,传入student。

class Person {}class Student extends Person {  studying(){}}function sayHello(p: Person){}const student = new Student()sayHello(student)

以上代码在编译的时候是没有问题的,但如果在sayHello办法中想要调用Student实例对象的studying,是不能够的,因为尽管传入的参数是Student的实例对象,但它在TypeScript中只能被检测为Person类型,而Person上是没有studying办法的。

要想正确调用,须要应用类型断言规定入参的理论类型

function sayHello(p: Person){  (p as Student).studying()}

非空类型断言

通过 !符号来使不能通过编译的代码不被标红揭示,但如果运行阶段代码存在问题,依然是会抛出谬误的。

字面量

通过const定义的变量的数据类型为字面量类型,字面量里的值就是该变量赋值的内容。

通过字面量类型,可用于规定变量的抉择范畴,比方 flex 布局的 direction 能够抉择 row 或者 colums

type DirectionType = "row" | "colums";let direction: DirectionType = "row";direction = "colums";

当变量赋值为它类型注解中所没有蕴含的内容时,是会标红揭示的。

类型放大

类型放大示意当变量数据类型的范畴比拟大时,咱们能够通过 if 、switch 、in 、typeof、instanceof 等形式进行判断来放大的变量的类型,以达到更精准的操作。

比方一个函数的参数类型可能为 string 和 number,间接获取 length 属性 是会报错的。因为只有 string 类型的变量能够获取到 length,但在 number 类型上是不存在的,所以此时能够通过 typeof 来判断入参类型,这个判断步骤也称为"类型爱护"。

这些ts中的类型注解,能够帮忙开发者更好标准开发时的代码,缩小线上故障~

以上就是对于TypeScript类型注解的内容,对于js和ts,还有很多须要开发者把握的中央,能够看看我写的其余博文,继续更新中~