美文网首页js css html
第一节:TypeScript变量与数据类型

第一节:TypeScript变量与数据类型

作者: 时光如剑 | 来源:发表于2022-04-05 21:45 被阅读0次

    1. 变量的类型注释

    在JavaScript中, 变量的复制相对灵活, 除了const外, letvar声明的变量可以赋予不同类型的数据

    例如:

    let val = 'string'
    console.log(typeof val)
    // 变量val的类型为string 类型
    
    val = 10
    console.log(typeof val)
    // 变量val的类型为number 类型
    
    val = true
    console.log(typeof val)
    // 变量val的类型为boolean 类型
    

    示例中, 变量val可以赋值不同类型的变量, 而变量的类型取决于赋予变量的值.

    如果我们需要限定变量的类型, 只允许给变量赋予某一种类型或几种基本类型 的联合类型, 我们就需要使用TypeScript给变量添加类型注释

    1.1 赋初值

    基础变量声明的语法
    let [变量]:[类型注释] = 值

    类型注释需要用来描述变量可以被赋予那些类型的值.

    // 1. 这样会报错,声明的变量是number类型,却被赋值为string类型的值
    let a:number = 'hello'
    
    // 2. 这样也会报错,声明string类型后中途重新赋值了其他类型的值
    let a:number = 20
    a = 'hello'
    
    

    这种方式实现的变量命名的好处,那就是在赋值的时候确定变量的类型,如果存值和声明的变量类型不符合就会报错
    声明类型的变量,将只能赋予相同类型的值

    如果声明变量赋初始值,在大多数情况下,添加类型注释并不是必须的, 原因在与TypeScript会根据我们赋予的初始值来自动推断变量的类型.

    例如:

    let a = 'hello'
    // let a: string
    
    a =  10
    // 不能将类型“number”分配给类型“string”
    

    TypeScript更加初始赋值'hello'推断变量astring类型, 此时在将其他类型数据赋值给变量a就会报错

    1.2 不赋初始值

    语法
    let [变量]:[类型注释]

    1. 如果只创造了变量并规定类型,那么这个变量默认值就是undefined
    2. 如果后面需要赋值时,还是只能按照 声明的变量类型来赋值,否则就会出错
    let num:number;
    console.log(num)  // undefined
    
    num = 10  // ok
    
    num = 'hello'
    // 错误:不能将类型“string”分配给类型“number”
    

    声明一个变量不管什么类型, 初始不赋值,变量默认为undefined,这是遵循JavaScript的语言规范,

    那么为什么undefined类型的值可以赋值给number类型的值呢? 那么先来了解一下TypeScript类型

    2. 数据类型

    TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。

    TypeScript 数据类型有:

    1. 数字类型 number
    2. 字符串类型 string
    3. 布尔类型 boolean
    4. undefined undefined
    5. null null
    6. 数组类型 []
    7. 元组 [] (数组的特殊形式)
    8. 对象类型 {}
    9. 函数类型 Function
    10. 任意类型 any
    11. void void
    12. never never
    13. unknown 不认识,代表 任何值,类似于any
    14. 枚举 enum

    2.1 字符串,数字,布尔类型

    和JavaScript 字符串,数字,布尔类型一样,并且所有数字都是浮点数。以及可以使用ES6字符串模板

    // 字符串类型
    let username = '张三'
    let person :string = `字符串模板${username}`
    console.log('person', person)
    
    // 数字类型
    let num: number = 30
    console.log('num', num)
    
    // 布尔类型
    let bol: boolean = true;
    console.log('bol',bol)
    
    2.2 数组类型

    JavaScript定义数组可以通过字面量和构造函数, TypeScript在添加数组的类型注释也不同的方式

    第一种就是使用字面量的方式

    // 正确的写法
    let arr: number[] = [10, 20, 30, 40];
    
    let arr: string[] = ['a', 'b', 'c', 'd'];
    // ...
    
    // 错误的写法
    let arr:[number] = [10, 20, 30, 40];
    // 这种写法指表示确定数组第一项的数据类型,其他的没有确定,报错
    

    number[]这种数组类型的定义方式, 其中[]表示是数组类型,number是基本数据类型, 表示数组每一项都是number类型

    第二种:使用内置的泛型Array

    // 或者使用泛型
    let arr: Array<number> = [10, 20, 30, 40];
    
    let arr: Array<string> = ['a', 'b', 'c', 'd'];
    // ...
    

    上面的示例中数组内所有的值都是同一种类型, 但在很多情况下数组内会有不同数据类型的值,

    那么就可以使用any类型或联合类型

    使用any类型定义数组内的元素类型

    let arr: any[]= [10, 'hello', true, null];
    let arr: Array<any> = [10, 'hello', true, null];
    
    // any表示任意类型,表示数组内每一项都可以是任意类型
    

    使用联合类型数组, 联合类型使用|符合,

    联合类型的前提是你明确的知道,数组内只能存那些类型的数据

    例如:我们希望一个数组只能存number,string两种类型的值

    let arr:(string | number)[] = ['hello' , 20, 'world']
    
    let arr:Array<string | number> = ['hello' , 20, 'world']
    

    (string | number)[]类型注释中[]表示为数组类型,(string | number)就是联合类型,表示数组没一项可以是string类型或number类型.满足一个即可

    2.3 元组类型

    元组类型其实就是另外一种Array数组 类型. 它确切的知道数组中包含多少元素, 以及它在特定位置包含哪些类型

    元组类型表示一个已知元素数量和每一项类型的数组,各元素的类型不必相同

    其实元祖类型就是单独定义数组的每一个数据的类型.

    // 正确的写法
    let arr:[number,string, boolean] = [10,'string',true]
    
    // 错误的写法
    let arr:[string,string, boolean] = [10,'string',true]
    // 编译时报错,Type 'number' is not assignable to type 'string'.
    // 不能将数字类型的值赋值给字符串类型
    
    // 注意定义数据类型和数据的数量保持一致, 数量不同则会报错
    let arr:[string,string, boolean] = [10,'string']
    // Property '2' is missing in type '[string, number]' but required in type '[string, number, boolean]'.
    

    也可以先声明元组类型的变量,之后再重新赋值

    let a:[string,number,number,boolean,object]
    
    // 这种 写法没问题
    a =  ["hello",1,2,true,{age: 18}];
    
    // 这种写法不行,上面创建变量时,要求的类型和值的类型按照顺序对不上
    a = [1, "hello" , 2, true,{age: 18}];
    
    // 这个写法也不可以,因为少了一个对象
    a = ["hello",1,2, true];
    

    TypeScriptde的一个好处就是,会在代码执行前的类型检查阶段抛出错误, 不想JavaScript只能在代码运行时,才知道发生了什么错误

    2.4 object 引用数据类型

    object是一个特殊的类型, 指定是任何不是原始值(string, number,bigint,boolean,symbol,null, undefined)的值.

    这与空对象类型{}不同, 也与全局类型Object不同

    object表示的是JavaScript中的引用类型,只要是具有属性的类型都可以使用object类型

    // 函数
    const fn:object = () => console.log('fn')
    
    // 数组
    const arr:object = [10,20]
    
    // 对象
    const obj:object = {name:'hello', age:18}
    
    

    因此这个类型在使用很少, 大多通过更详细的类型添加类型注释.

    例如:

    // 函数类型注释
    const fn:() => void = () => console.log('fn')
    
    // 数组类型注释
    const arr:number[] = [10,20]
    
    // 对象
    const obj:{name:string,age:number} = {name:'hello', age:18}
    
    2.5 对象类型

    除了基本数据类型, 最常见的类型是对象类型. 对象类型是值任何带有属性的JavaScript值

    对象类型几乎是所有的属性都要定义对象类型.

    通过关键字object定义对象类型

    // 对象类型
    let ob:object =  { a: 10 }
    

    这种类型注释的对象并不限定属性数量与属性值的类型. 可以赋值任意类型

    也可以通过字面量方式,列出所有属性以及属性类型来进行类型注释

    let student:{name:string,age:number} = {name:'张三',age:18}
    
    2.6 Function 类型

    Function为全局类型, 描述JavaScript中所有函数值的属性, Function类型总是可以调用类型值的特殊属性, 这些调用返回any, 一般也不常用

    function example(fn:Function){
        return fn(1,2)
    }
    

    参数fn是一个具有函数属性的函数类型, fn()的调用是一个无类型的函数调用, 因为返回类型为any类型不太安全.最好避免使用,.

    可以使用更加详细的函数类型注释

    例如:

    function example(fn:() => void){
        return fn(1,2)
    }
    
    2.7 任意类型 any

    TypeScript也有一个特殊的类型: any类型,当你不希望某个特定的值导致类型检查错误时,可以使用它

    通常当你声明一个变量, 没有确定初始类型,也没有赋初始值是,或者赋初值为undefined或null时, 变量的类型默认为any类型.

    也就是说:当您不指定类型,并且 TypeScript 无法从上下文中推断出它时,编译器通常会默认为any.

    any类型的变量赋值任何类型的数据都不会报错

    let a = null
    // 或者
    let a = undefined
    // 或者
    let a;
    // let a: any
    
    a = 'aa'
    console.log(a) // 'aa'
    a = 30
    console.log(a) // 30
    

    一般来说并不建议大量使用any类型.当你明确知道一个变量之后不会被赋予其他类型的数据, 那么就可以在声明变量时添加详细的类型注释;

    只有当你在不确定变量未来会赋予什么样类型的值时, 可以尝试使用

    注意:

    any类型的变量会跳过类型检查

    例如:

    let obj: any = { x: 0 };
    
    // 下面代码将没有一行代码编译错误
    obj.foo();
    obj();
    obj.bar = 100;
    obj = "hello";
    const n: number = obj;
    

    实例中变量objany类型, 因此obj身上的所有操作都会跳过类型检查, 因此在TypeScript编译代码时不会报错.

    但是执行编译后的代码可能会出错.

    2.8 空类型 void undefined null

    Void 表示没有任何类型 空
    通常声明一个Void 类型没什么意义,因为这个类型的变量只能赋值为undefined和null

    let a: void = undefined;
    console.log(a)
    
    let a: void = null;
    console.log(a)
    
    // 赋值其他类型的值就会报错
    let a: void = 123;
    console.log(a)
    // 报错:不能将类型“number”分配给类型“void”
    

    在TypeScript里,undefined和null 两者各自都有自己类型分别叫做undefined和null;和void相似,他们的类型本身用处不大:

    // 声明一个undefined类型变量
    let und: undefined;
    und = undefined;
    und = null;
    console.log(und)
    
    // 声明一个null类型的变量
    let nul: null
    nul = null;
    und = undefined;
    console.log(nul)
    

    void一样, undefinednull类型只能赋值undefinednull值, 本身意义不大

    默认情况下,null和undefined 是 所有类型的子类型
    就是说你可以把null和undefined赋值给其他类型的变量

    let num:number = undefined;
    let num:number = null;
    let str:string = undefined;
    // ....
    

    但是,不能将其他类型的值赋值给void,undefined,null类型的变量

    let un:undefined =  12;
    let aa:null = 'aa';
    let bb:void = true;
    

    这样写会报错

    2.9 never类型

    never类型表示的是那些永不存在的值的类型
    这个严格来说算不上新的数据类型,只是开发者对于一些值所起的作用的判断而已

    比如:

    1. 总是会抛出异常,throw错误或是返回一个error类型的数据
    2. 根本就不会有返回值的函数表达式(死循环函数)
    // 没有返回值
    function error(msg:string):never {
      throw new Error(msg)
    }
    
    // 一旦有了返回值never类型就报错
    function error():never {
      retrun new Error('something failed')
    }
    // 报错: 不能将类型“Error”分配给类型“never”。
    
    // 哪怕没有显示的return 也会报错, 因为函数有默认返回undefined
    function error():never {
      new Error('something failed')
    }
    // 返回“never”的函数不能具有可访问的终结点。
    
    
    // 死循环函数
    function infiniteLoop():never{
      while(true){
        console.log('帅")
      }
    }
    

    never类型是任何类型的子类型,任何其他类型的值都不能赋值给never类型.即使any也不可以

    let n:never;
    n = 12
    // 不能将类型“number”分配给类型“never”
    
    2.10 unknown 类型

    unknown类型代表任何值, 这类似于any类型, 但更安全, 因为用值做任何事情都是不合法的

    例如:

    function fn1(a:any){
        // 调用any类型的属性是合法的
        // 任意类型有可能是对象类型
        a.b()
    }
    
    
    function fn2(a:unknown){
        // unknown 未知类型, 不确定它是什么值
        a.b()
        // 报错:类型“unknown”上不存在属性“b”。
    }
    
    2.11 枚举类型

    枚举类型是TypeScript添加到JavaScript的一项功能, 它允许描述一个值, 该值可能是一组可能的命名常量之一.

    与大多数TypeScript功能不同,这不是对JavaScript的类型级添加, 而是添加到语言和运行时的东西.

    详细内容稍后章节介绍

    相关文章

      网友评论

        本文标题:第一节:TypeScript变量与数据类型

        本文链接:https://www.haomeiwen.com/subject/kkjlsrtx.html