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

TS的基本类型

  • number:数字

      let num:number=2
    
  • string:字符串

      let name:string='井底的蜗牛'
    
  • 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)

 

 

TS的基本类型约束就到这里,感谢大佬们的观看,如有问题欢迎在评论区留言

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值