TS学习(四) :TS基本类型约束的使用

TS的基本类型


number:数字

 

 let num:number=2


string:字符串

 

 let name:string='fcc study ts'


boolean:布尔

 

const target: boolean = false


数组

这里值得注意:数组的约束 不能这样let arr: []= [1,2,3]写; 只能 let arr: []= [] 或者加类型约束let arr: string[] 这里先不做解释为什么,到后面会详解

数组每一项都是数字 ,一般是使用: number[],也可以使用构造函数的方式: Array<number>,这两种方式是一样的

  const arr: number[] = [1,2,3,4]
  const arr2:Array<number>=[1,2,3,4]


数组每项都是字符串,: string[]

 

 const arr: string[] = ['1','2','3','4']
 const arr2: Array<string> = ['1','2','3','4']


数组每一项是对象 : {}[], 当然如果每个对象里面有些字段需要约束则,需要进行约束, 如每个对象中必须有个uid位置值且是string,: {uid: string}[]

  const arr: {uid: string}[] = [{uid: 'jiandidewoniu'}]
  const arr2: Array<{uid:string} >= [{uid: 'jiandidewoniu'}]


数组的每一项是一个数组: number[][] = [[1,2],[3,4,],],多维数组就和一维数组一样,嵌套就可以

  const arr: number[][] = [[1,2],[3,4,],]
  const arr2:Array<Array<number>>=[[1,2],[3,4,],] 


  如果你使用的是Array<Array<number>>这种方式的这里得注意了,
  如果书写代码规范 喜欢在定义的时候打上空格,那就没啥事,那是你习惯很好,
  可能就不不会发现这个东西,【Array<Array<number>>=】这里的【>>=】,
  如果你不在等号【=】两边加上控制,就会出现问题,可能编译器就会认为你这里既然是大于等于【>=】了,
  前面就不需要在加一个大于【>】,虽然运行后没啥问题,但是对于代码规范,还是习惯在等于号两边加上空格更好些【let a: string = 'a'】


数组里面类型不是固定的,则可以这样写,用 “|” 或符号: string[] | number[] | {}[] | [类型1,类型2,...][],这样你这个数组就啥类型都可以了,但是数组中类型只能有一个,要么都是string,要么都是number,要么都是对象,要么都是二维数组,当[][]二维数组,里面没有任何东西时,赋值的时候也只能是空,不然会报错,如果[1,2][]那么二维数组里面每一项都只能是[1,2],且顺序不能变

let arr3: string[] | number[] | boolean[]  | [number,string][] = ['1','3','5']
let arr4: string[] | number[] | boolean[]  | [number,string][] = [1,3,5]
let arr5: string[] | number[] | boolean[]  | [number,string][] = [[1,'2'],[3,'4'],[5,'3']]
let arr6: string[] | number[] | boolean[]  | [][] = [[],[],[]]
let arr7: string[] | number[] | boolean[]  | [1,2,3][] = [[1,2,3],[1,2,3],[1,2,3]]


对象

object:: object 这样只能约束变量是否是对象,至于对象内容是啥他就不管,只要是对象就像,约束力没那么强

  const obj: object = {}


{}: : {对像内容约束},如果{},里面没有约束的化,其实和object 没啥区别,如果加上内容约束,

比如 :{name: string} 这样名字只能是string 不能是其他类型

  let obj: {} = {name:'333'}
  let obj2: object = {name:111}
 
  let obj3: {name: string} = {name: 'aaa'}


null 和undefined ,这两个类型比较特殊,他们是所有其他类型的子类型,他们可以赋值给其他类型,都不会报错,

但是会有一些隐患,如一个字符串本来是有一些方法,如substr方法,结果你的值是null,或者undefined

而他们就没有substr方法 就会报错

 

  let num: number = null
  let str: string = undefined
  console.log(str.substr(0, 1));
  let arr: string[] = null


为了解决这样的隐患 我们可以在tsconfig配置里面的编译选项中加上一个配置"strictNullChecks" : true,

加上这个配置后你的类型就不能赋值给null/undefined了,变成了更严格的空类型检查,从此之后 null/undefined只能赋值给自身了

    "compilerOptions": {
        "target": "es2016",
        "module": "commonjs",
        "lib":["es2016"],
        "outDir": "./dist",
        "strictNullChecks": true
    },


联合类型


当一个变量可以是字符串也可以为空时,如果还用之前的约束方式就不可能实现,之前的约束是必须有值,

当然你可能已经接触过了,之前的数组中每一项都是不同的值时 当时我们就用了 string | number来进行约束的,

中间这个|表示的就是联合符号 例如 名字有可能不填,那么我们怎么进行约束呢

 

  let name: string | undefined;
  let age:  number | undefined;


像这样约束方式就是联合类型,就可以处理当变量是多种类型的情况下的约束,

注: 在这种情况下就得判空处理,否则如果使用了一些内部函数如toString等,当值为undefined时就会报错;

如果进行了类型保护就不会出现这种问题; 如何触发类型保护呢,一般使用typeof触发简单的类型保护

void类型

通常用于约束函数的返回值,表示该函数没有任何返回值;一般不会约束变量
 

    function print: voild(){
        console.log(window)
    }


never类型

通常用于约束函数的返回值,表示该函数永远不可能结束;可以约束变量,但一般不会去这样约束
   

 function throwError(msg: string): nrver {
        throw new Error(msg);
    }
 
 function alwaysDoSomething(): never {
      while (true){
            //...
      }
  }


字面量类型:

表示使用一个值进行约束


强制性把变量的值给固定了,后面赋值只能赋值你约束的字面量的值,如下:

let a: "A";


如果你想改变a的值,它是会报错的,告诉你不能赋值除“A”以外的值

a="B"


一般我们可以进行这样约束,比如对性别进行约束,

let gender: "男" | "女" | "未知";


在赋值的时候,我们只能选择“男”,“女”和“未知”这三种结果

注:在之前数组的时候提到过 为什么let arr: []= [1,2,3]不能这样写了,知道为什么了吗

在这里解释一下,字面量约束一个变量为数组,怎么进行约束,数组的符号是[],那么我们约束是不是就可以写成这样

  let arr: [];


但是这个时候,你是不是就相当于把arr的值固定只能是[],这里这个符号表示的可是一个空数组;所有接下来你想给arr赋值,只能是

 

arr = [];


不能给数组里面加入任何东西,所有这样写let arr: []= [1,2,3]是错误的,正确的写法是

 

 let arr1: []= []; 或者
  let arr2: [1,3,4,5]= [1,3,4,5];或者
  let arr3: [1,2,3];
  arr3 = [1,2,3];


所以,对数组进行约束,必须得在前面加上数组的类型,否则就变成了字面量约束了,

这个时候你是不是会想到 对象,给对象约束的时候好像也是let obj: {} = {name: '333'};

按照数组的例子,这按理来说是一个空对象 不应该可以进行塞值,但是恰恰相反对象这样进行赋值没有问题,

这里想要深究可能得看源码了,我就没有去过多的研究,只是好奇的想了一下,可能是数组的一个长度问题;这就不进行深究了

元组类型(Tuple) :

一个固定长度的数组,并且数组中的每一项的类型确定
如 定义一个数组的第一项为字符串,第二项为数字

let arr: [string, number];


如果给数组赋值为空数组,结果报错不行

arr = [];


如果给数组第一项赋值为数字,也不行

arr = [1,'2'];


如果给数组长度超过两项也不行,即使是约束对了但是长度不对也不行,

arr= ["1",2,3]


只有长度,每一项都对了才行

arr= ["1",2]


any类型:

any类型可以绕过类型检查,因此,any类型的数据可以赋值给任意类型
一般不建议使用any类型进行约束,在运行中可能会存在问题,如:

let data: any = "admin";
let num: number = data;


在写的过程中不报错,但是在运行的时候会出现问题

类型别名:对已知的一些类型定义名称;

语法 type 类型名称 = 约束的东西
先看一下代码

let user:{name:string,age:number,gender:"男"|"女"|"未知"};
function getUser(g: "男"|"女"|"未知"):{name:string,age:number,gender:"男"|"女"|"未知"}[]{
    //...
    return [];
}


这个函数是获取的用户数据,首先参数有约束,返回值也有约束,咋一看没啥问题,确实没问题;

但是看起来不太美观,而且有重复的东西;到时候要修改还得一个一个去改麻烦

这个时候我们就可以用到我们的类型别名,就是把公共的约束封装起来,统一维护

那么我们对以上代码进行使用类型别名

type Gender = "男"|"女"|"未知"
type User = {name:string,age:number,gender:Gender};
let user: User;
function getUser(g:Gender): User[]{
    //...
    return []
}


这样写完 代码看起来也比较舒适,要修改类型约束时只要改Gender和User的约束就可以了

函数的约束


函数重载:在函数实现之前,对函数调用的多种情况进行声明

举个例子,下面combine函数的返回值可能是数字,也可能是字符串,

 

function combine(a: number | string, b: number | string): number | string {
        if (typeof a === "number" && typeof b === "number") {
        return a * b;
        } else if (typeof a === "string" && typeof b === "string") {
        return a+b;
        }
        throw new Error("a和b必须时相同的类型")
  }


当你去调用函数传参时,不管你传递任何类型 都不会报错

  let result = combine(1,'3')
如果不看函数的返回值我们是不知道必须传什么值才能得到返回值,所以最好可以在调用函数的时候就进行提示

这里我们就可以用到函数的重载 语法function 函数的名字(参数1:约束类型,参数2:约束类型,...): 约束类型(这里只写一个)

  /**
  * 得到a*b的结果
  * @param a 数字类型
  * @param b 数字类型
  */
  function combine(a: number , b: number ): number;
  /**
  * 得到a+b的结果
  * @param a 字符串类型
  * @param b 字符串类型
  */
  function combine(a: string, b:  string): string;
  function combine(a: number | string, b: number | string): number | string {
      if (typeof a === "number" && typeof b === "number") {
          return a * b;
      } else if (typeof a === "string" && typeof b === "string") {
          return a+b;
      }
      throw new Error("a和b必须时相同的类型")
  }

像这样的写法,在调用函数的时候,如果你输入的两参数类型不同,会有报错提示,只要正确了才不会报错

 

 let result = combine(1,3)

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值