day2-TS学习之旅-数据类型1

常用类型

本文介绍了any、unknown、 never、void、object、tuple(元组)

  • any:任意类型,一旦将变量类型限制为any,那就意味着放弃了对该变量的类型检查

    //明确的表示a的类型是any——显示的any
    let a:any
    //以下对a的赋值,均无警告
    a=100
    a='你好'
    a=false
    
    //没有明确的表示b的类型是any,但TS主动推断出b是any——隐式的any
    let b
    //以下对b的赋值,均无警告
    b=100
    b='你好'
    b=false
    

    注意:any类型的变量,可以赋值给任意类型的变量

    let c:any
    c=9
    let x:string
    x=c //无警告
    
  • unknown:未知类型

    • unknown可以理解为一个数据安全的any,适用于不确定数据的具体类型
      let a:unknown
      
      //以下对a的赋值,均正常
      a=100
      a=false
      a='你好'
      
      //设置x的数据类型为string
      let x:string
      x=a  //警告:不能将类型‘unknown’分配给类型‘string’
      
    • unknown会强制开发者在使用之前进行类型检查,从而提供更强的类型安全性
      //设置a的类型为unknown
      let a:unknown
      a='hello'
      
      let x:string
      //第一种方法:加强类型判断
      if(typeof a==='string'){
      x=a
      }
      //第二种方法:断言
      //断言(两种写法):类型断言会告诉编译器,你不用给我进行检查,相信我,他就是这个类型
      x=a as string  //(推荐这种断言)
      x=a
      
    • 读取any类型数据的任何属性都不会报错,而unknown正好与之相反
      let str1:sting
      str1='hello'
      str1.topUpperCase() //无警告
      
      let str2:any
      str2='hello'
      str2.topUpperCase() //无警告
      
      let str3:unknown
      str3='hello'
      str3.topUpperCase() //警告:‘str3’的类型为‘未知’
      
      //使用断言强制指定str3的类型为string
      (str3 as string).topUpperCase() //无警告
      
  • never:任何值都不是,简言之就是不能有值,undefined、null、‘’、0都不行!

    • 几乎不用never去直接限制变量,因为没有意义

      //指定a的类型为never,就意味着a以后不能存任何的数据了
      let a:never
      
      //以下对a的所有赋值都会有警告
      a=1
      a=true
      a=undefined
      a=null
      
    • never一般是TS主动判断出来的,例如

      let a:string
      a='hello'
      
      if(typeof a==='string'){
      console.log(a.toUpperCase())
      }else{
      console.log(a) //TS会判断出此处的a是never,因此没有任何一个值符合此次的逻辑
      }
      
      
    • never也可以用于限制函数的返回值

      //限制throwError函数不需要有任何返回值,任何值都不行,像undefined、null都不行
      function throwError(str:string):never{
      throw new Error('程序异常退出:'+str)
      }
      
  • void:通常用于函数返回值声明,含义:【函数不返回任何值,调用者也不应依赖其返回值进行任何操作】

    function logMessage(msg:string):void{
    console.log(msg)
    }
    logMessage('你好')
    

    注意:编码者没有编写return去指定函数的返回值,所以logMessage函数是没有显示返回值的,但会有一个隐式返回值,就是undefined:即虽然函数返回类型为void,但也是可以接受undefined的,简单记:undefined是void可以接受的一种空

    • 以下写法均符合规范
      function logMessage(msg:string):void{
      	console.log(msg)
      }
      
      function logMessage(msg:string):void{
      	console.log(msg)
      	return;
      }
      
      function logMessage(msg:string):void{
      	console.log(msg)
      	return undefined
      }
      
    • 那限制函数返回值时,是不是undefined 和void 就没区别呢?——有区别,【返回值类型为void的函数,调用者不应依赖其返回值进行任何操作
      function demo1():void{
      console.log('hello')
      }
      let result=demo1()
      if(result){  // 警告:无法测试‘void’类型的表达式的真实性
      }
      
      function demo2():undefined{
      console.log('hello')
      }
      let result=demo2()
      if(result){  //无警告
      }
      
    • 理解 void 与undefined
      • void是一个广泛的概览,用来表达‘空’,而undefined则是这种‘空’的具体实现之一。
      • 因此可以说undefined是void能接受的‘空’状态的一种具体形式。
      • 换句话说:void包含undefined,但void表达的语义超越了单纯的undefined,它是一种意图上的约定,而不仅仅是特定值的限制
    • 总结:若函数返回值为void,那么:
      • 从语法上讲:函数是可以返回undefined的,至于显示返回,还是隐式返回,这无所谓
      • 从语义上讲:函数调用者不应关心函数返回的值,也不应依赖返回值进行任何操作!即使返回了undefined值
  • object与Object:实际开发中用的相对较少,因为范围太大了

    • object:所有非原始类型 ,可存储:对象、函数、数组等,由于限制的范围比较宽泛,在实际开发中使用的相对较少
      let a:object  //a的值可以是任何【非原始类型】,包括:对象、函数、数组等
      //以下代码,是将【非原始类型】赋给啊,所以均符合要求
      a=[]
      a={name:'张三'}
      a=[1,2,3,4,5]
      a=function(){}
      a=new String('123')
      class Person{}
      a=new Person()
      
      //以下代码,是将【原始类型】赋给a,有警告
      a=1  //警告:不能将类型“number”分配给类型“object”
      a=true  //警告:不能将类型“boolean”分配给类型“object”
      a='你好'  //警告:不能将类型“string”分配给类型“object”
      a=null  //警告:不能将类型“null”分配给类型“object”
      a=undefined  //警告:不能将类型“undefined”分配给类型“object”
      
    • Object: 可以存储所有可以调用Object方法的类型;(即除了undefined、null的任意值)
      let b:Object  //b的值必须是Object的实例对象,(即除了undefined、null的任意值)
      //以下代码,均符合要求
      b=[]
      b={name:'张三'}
      b=[1,2,3,4,5]
      b=function(){}
      b=new String('123')
      class Person{}
      b=new Person()
      b=1 
      b=true 
      b='你好'  
      
      //以下代码,有警告
      a=null  //警告:不能将类型“null”分配给类型“Object”
      a=undefined  //警告:不能将类型“undefined”分配给类型“Object”
      
    • 声明对象类型
      • 实际开发中,限制一般对象,通常使用以下形式
        //限制person1对象必须有name属性,age为可选属性
        let person1:{name:string,age?:number}
        //含义同上,也可用 ; 分割
        let person1:{name:string;age?:number}
        //含义同上,也可用 换行 分割
        let person1:{
        name:string
        age?:number
        }
        
        //以下赋值均可以
        person1={name:'李四',age:12}
        person2={name:'李四'}
        person3={name:'李四'}
        
        //以下赋值会有警告:因为person3中的类型限制中,没有对gender属性的说明
        person3={name:'李四',gender:'男'}
        
      • 索引签名:允许定义对象可以具有任意数量的属性,这些属性的键和类型是可变的,常用于:描述不确定的属性(具有动态属性的对象)
        //限制person对象必须有name属性,可选age属性但值必须是数字,同时可以有任意数量、任意类型
        let person:{
        name:string
        age?:number
        [key:string]:any //索引签名,完全可以不用key这个单词,换成其他的也可以
        }
        // 赋值合法
        person={
        name:'张三',
        age:18,
        gender:'男'
        }
        
    • 声明函数类型
      let count:(a:number,b:number)=>number
      count=function(x,y){
      return x+y
      }
      
      备注:
      • TS中的=>在函数类型声明时表示函数类型,描述其参数类型和返回类型
      • JS中的=>是一种定义函数的语法,是具体函数实现
      • 函数类型声明还可以使用:接口、自定义类型等方式,下文会详细讲解
    • 声明数组类型
      let arr1:string[]
      let arr2:Array
      
      arr1=["a","b","c"]
      arr2=["a","b","c"]
      
      备注:上述代码中的Array属于泛型,下文会详细讲解
  • tuple
    元组(tuple)是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的且可以不同,元组用于精确描述一组值的类型,?表示可选元素

    //第一个元素必须是 string 类型,第二个元素必须是 number 类型
    let arr1: [string, number]
    // 第一个元素必须是 string 类型,第二个元素是可选的,如果存在,则必须是 number 类型
    let arr2: [string, number?]
    // 第一个元素必须是 number 类型,后面的元素可以是任意数量的string类型
    let arr3: [number, ...string[]]
    
    
    //可以赋值
    arr1 = ["a", 1]
    arr2 = ["a", 1]
    arr2 = ["a"]
    arr3 = [1, "a", "b", "c"]
    arr3 = [1]
    
    //不可以赋值,因为arr1的类型是[string, number],所以不能有第三个元素
    arr1 = ["a",1,2]
    

你可能感兴趣的:(学习,前端,typescript)