使用TypeScript类型注解的方法

目录
  • 类型注解
  • 类型推导
  • TS和JS共有的数据类型
  • TS独有的数据类型
    • any
    • unknown
    • void
    • never
    • tuple
    • 函数参数和返回值
    • 类型断言
    • 非空类型断言
    • 字面量
    • 类型缩小
  • 总结

类型注解

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

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

这样保证变量的数据类型是固定的,那么它所能使用的方法也是确定的,不会出现变量本来是字符串,调用了 toUpperCase方法,后来在未测试到的某场景无意中把它改为数字类型后,调用 toUpperCase 直接报错的情况。

类型推导

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

TS和JS共有的数据类型

TypeScript包含了JavaScript所拥有的数据类型,stringnumbersymbolarraybooleanundefinednullobject

其中,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 = true
let 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 来判断入参类型,这个判断步骤也称为"类型保护"。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • TypeScript基础类型介绍

    目录 1.基础类型 2.对象类型 2.1数组 2.2元组 2.3对象 3.类型推断 3.1类型联合中的类型推断 3.2上下文类型 4.类型断言 TS 的静态类型可以人为的分为两类: 基础类型:像布尔值(boolean).数字(number).字符串(string).Any(任意类型).Void(无类型).Null. Undefined.Never(无值类型) 对象类型:像数组.函数.对象.枚举.元组. 1.基础类型 TS的类型定义主要通过以下示例代码中演示的方式进行定义: ;(function

  • 在Vue 中使用Typescript的示例代码

    Vue 中使用 typescript 什么是typescript typescript 为 javaScript的超集,这意味着它支持所有都JavaScript都语法.它很像JavaScript都强类型版本,除此之外,它还有一些扩展的语法,如interface/module等. typescript 在编译期会去掉类型和特有语法,生成纯粹的JavaScript. Typescript 5年内的热度随时间变化的趋势,整体呈现一个上升的趋势.也说明ts越来越️受大家的关注了. 安装typescrip

  • TypeScript枚举类型

    目录 1.概述 2.数字枚举 2.1反向映射 3.字符串枚举 4.const枚举 5.总结 1.概述 所谓的枚举类型就是为一组数值赋予名字. enum类型在C++.Java语言中比较常见,TypeScript在JavaScript原有的类型基础上也增加了enum类型. 比如我们需要定义一组角色,需要使用数字表示,就可以使用如下代码定位: enum role{ STUDENT, TEACHER, ADMIN } 上面代码中我们定义了role为一个枚举类型,这个里面有是三个值,TypeScript会

  • 一文了解TypeScript数据类型

    目录 基础类型 any类型 数组 元组 Interface 函数 类型自推 联合类型(二选一甚至多选一) class 枚举 基础类型 ts中支持更多的类型 let age: number = 10 // Number let firstName: string = '凉宸' // String let lastName: string = '凉宸' // String let isMary: boolean = true // boolean let unde: undefined = unde

  • TypeScript中的函数和类你了解吗

    目录 函数 作为参数 定义函数 函数参数的类型 可选类型 参数默认值 剩余参数 this的默认推导 函数重载 类 初始化 继承 多态 成员修饰符 总结 函数 以下声明了一个函数类型,通过type来定义类型别名,void 表示没有返回值 type fnType = () => void; 作为参数 函数可以作为参数,传递到另一个函数中 type fnType = () => void; function foo(fn: fnType) { fn(); } function bar() { con

  • TypeScript中的接口和泛型你了解吗

    目录 接口 对象类型 索引类型 函数类型 继承 交叉类型 接口实现 interface和type的区别 字面量赋值 枚举类型 泛型 泛型函数 泛型接口 泛型类 类型约束 总结 接口 使用 interface 关键字来定义数据类型 对象类型 当存在于较长的数据类型约束时,我们可以通过 type 关键字 为类型注解起别名,也可以通过接口来定义 type UserType = { name: string; age?: number }; const user: UserType = { name:

  • 使用TypeScript类型注解的方法

    目录 类型注解 类型推导 TS和JS共有的数据类型 TS独有的数据类型 any unknown void never tuple 函数参数和返回值 类型断言 非空类型断言 字面量 类型缩小 总结 类型注解 TypeScript提供了很多数据类型,通过类型对变量进行限制,称之为类型注解,使用类型注解后,就不能够随意变更变量的类型. 以下代码定义了一个字符串类型的变量,如果把它更改为数字类型时,代码编译阶段就会直接报错,提示 “Type ‘number’ is not assignable to t

  • 使用TypeScript类型注解的方法详解

    目录 类型注解 类型推导 TS和JS共有的数据类型 TS独有的数据类型 any unknown void never tuple 函数参数和返回值 类型断言 非空类型断言 字面量 类型缩小 总结 类型注解 TypeScript提供了很多数据类型,通过类型对变量进行限制,称之为类型注解,使用类型注解后,就不能够随意变更变量的类型. 以下代码定义了一个字符串类型的变量,如果把它更改为数字类型时,代码编译阶段就会直接报错,提示 “Type ‘number’ is not assignable to t

  • 为react组件库添加typescript类型提示的方法

    以我自己的组件react-better-countdown为例, 首先在package.json里面添加types: types/index.d.ts, , 然后文件目录上添加对应文件夹和文件, 最后是index.d.ts文件的编写,具体看代码: import * as React from 'react'; interface CountdownProps { count?: number; dayText?: string | React.ReactElement; hourText?: s

  • 详解Anyscript开发指南绕过typescript类型检查

    目录 前言 场景设定 解决方法 注释忽略 场景用例 类型断言 场景用例 泛型转换 场景用例 总结 前言 随着越来越多的前端项目采用 typescript 来开发,越来越多前端开发者会接触.使用这门语言.它是前端项目工程化的一个重要帮手,结合 vscode 编辑器,给予了前端开发者更严谨.高效的编码体验.但同时,严格的类型检查也会使部分开发者的编码效率有所降低,将时间花费在解决类型冲突.类型不匹配上,从而导致望而却步,迟迟不敢上手. 本文描述了几种绕过 typescript 类型检查的方法,帮助t

  • Python中typing模块与类型注解的使用方法

    实例引入 我们知道 Python 是一种动态语言,在声明一个变量时我们不需要显式地声明它的类型,例如下面的例子: a = 2 print('1 + a =', 1 + a) 运行结果: 1 + a = 3 这里我们首先声明了一个变量 a,并将其赋值为了 2,然后将最后的结果打印出来,程序输出来了正确的结果.但在这个过程中,我们没有声明它到底是什么类型. 但如果这时候我们将 a 变成一个字符串类型,结果会是怎样的呢?改写如下: a = '2' print('1 + a =', 1 + a) 运行结

  • Java8中的类型注解浅析

    注解大家都知道,从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置.那充满争议的类型注解究竟是什么?复杂还是便捷? 一.什么是类型注解 在java 8之前,注解只能是在声明的地方所使用,比如类,方法,属性:java 8里面,注解可以应用在任何地方,比如: 创建类实例 复制代码 代码如下: new @Interned MyObject(); 类型映射 复制代码 代码如下: myString = (@NonNull String) str; i

  • Java8新特性之类型注解_动力节点Java学院整理

    注解从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置.那充满争议的类型注解究竟是什么?复杂还是便捷? 什么是类型注解 在java 8之前,注解只能是在声明的地方所使用,比如类,方法,属性:java 8里面,注解可以应用在任何地方,比如: 创建类实例 new @Interned MyObject(); 类型映射 myString = (@NonNull String) str; implements 语句中 class Unmodif

  • TypeScript类型声明书写详解

    本文总结一下TypeScript类型声明的书写,很多时候写TypeScript不是问题,写类型就特别纠结,我总结下,我在使用TypeScript中遇到的问题.如果你遇到类型声明不会写的时候,多看看lodash的声明,因为lodash对数据进行各种变形操作,所以你能遇到的,都有参考示例. 基本类型 // 变量 const num: number = 1; const str: string = 'str'; const bool: boolean = true; const nulls: null

  • Vue项目中使用flow做类型检测的方法

    在vue2.0的项目中加入flow类型检查.当前项目是用js写的,当项目越来越大,由于js弱类型的特性,相比ts(typescript)这种强类型的语言而言,后期维护会越来越困难.为了解决这个问题,决定使用flow 加入类型检查. flow了解 flow是fackbook公布的javascript静态类型检查器. 可以检查js中一些bug,eg:自动类型转换中出现的问题.flow官网 首先,安装flow npm i flow-bin --save-dev 然后在package.json中添加脚本

  • mybatis自动生成@Table、@Column、@Id注解的方法

    在pom.xml中添加如下插件以及插件相关的依赖 <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <!--配置文件的位置--> <configurat

随机推荐