乐趣区

关于前端:TypeScript防脱发级入门基本类型检查

嗨!大家好!我是法医,一只医治系前端码猿🐒,与代码对话,聆听它们心底的呼声,期待着大家的点赞👍与关注➕。

1. 如何进行类型束缚

类型束缚其实很简略,只须要在 变量 函数参数 函数返回值 地位上加上 : 类型 就能够了。

举个栗子 🌰:变量

// 咱们定义变量的时候,必定是晓得这个变量是寄存什么类型的数据

let name:string = "法医";

一旦给 name 赋值其它类型,立马会提醒谬误

举个栗子 🌰:函数参数和返回值

// 参数前面 :number 示意传的参数必须是数字类型,而 test 函数前面的:number 示意返回值是数字类型
function test(a:number,b:number):number {return a + b;}
test(1,2);// 当调用 test 函数传值为数字示意能够失常运行,传其它类型则会报错

传入字符串就会报错

当咱们写一个函数的时候,咱们十分分明函数的参数以及返回值是什么类型的,此时咱们能够束缚好类型,在之后的调用中咱们能够释怀的调用函数,因为只有写错了,立马会提醒谬误,不须要等到程序运行后再提醒谬误,这些在 JS 中是做不到的,然而在 TS 中很轻松能够做到,不仅如此,类型查看还带来很多益处,比方说:

举个栗子🌰:

JS 中咱们是没有方法确定上面代码中 text(1,2) 调用的就是一个函数,中途有可能 test 会被批改,而后调用函数就会报错

function test(a,b) {return a + b;}
// 很多行代码
test = 123;
// 很多行代码
test(1,2);

然而在 TS 中这种状况相对是不容许的 🙈

因为 TS 晓得函数 test 和调用函数 test 是同一个货色,于是就呈现一个神奇的成果——当须要给函数重新命名的时候,双击函数 test并且按 F2,函数名改了,调用函数名也跟着改了,之所以会达到这个成果,是因为TS 有严格的类型查看零碎,它晓得调用函数的 test 用的就是 test 函数,它们两者之间是建立联系的

不仅如此,还有一种成果:当咱们 点击调用函数 并且按F12,它会跳到定义的函数地位,

为了让咱们少写点代码,应用 TS 进行束缚的时候,TS 在很多场景中能够实现 类型推导

举个栗子🌰:

当咱们把函数返回值束缚去掉当前仍然能够从提醒中发现返回值是 number,这是因为咱们将参数束缚为number,数字与数字相加仍然是数字,所以最初函数也会返回number,赋值给变量 result,TS 还会智能地发现函数返回的后果是 number,所以result 类型也是 number,因而咱们只须要在参数地位加上类型束缚就能够了,TS 在每个中央都有类型查看,是不是很牛逼🐮

📢 那问题来了:我怎么晓得这类型推导什么时候能推导胜利,什么时候推导失败呢?

👉 解答:

有个小技巧,当咱们看到变量或者函数的参数呈现 三个小点 ,这 三个点 就是在揭示:你给我当心点,我的确做不到了,示意以后没有推导进去到底是什么类型,能够用 any 类型 来示意,这时就须要手动束缚一下,

any:示意任意类型,对该类型,TS 不进行类型查看

2. 根本类型

留神是首字母是小写

  • number:数字,

    let figure:number = 6;
  • string:字符串

      let user:string = "法医";
  • boolean:布尔值

      let fake:boolean = false;
  • array:数组

    :number[]这种写法其实是语法糖,真正的写法是上面第二种,这两种写法都能够束缚数组的,看集体爱好,倡议应用第一种,因为在 react 中尖括号示意组件,Array<number>可能会造成抵触

      let arr:number[] = [1,2,3];
    
      let arr:Array<number> = [1,2,3];
  • object:对象

    object束缚不是很罕用,因为 object 约束力不是很强,它只能束缚一个对象,却不能束缚对象外面的内容,然而有时会用到

    // 传入一个对象,输入 value 值
      function getValues(obj:object) {let vals = Object.values(obj);
       console.log(vals); // 输入 法医  18   
      }
      getValues({
       name:"法医",
       age:18
      })
  • null 和 undefined

    nullundefined 须要重点说一下,nullundefined 是所有其余类型的子类型,它们能够赋值给其它类型,然而又会产生隐患,上面办法调用都会报错,因为束缚了是 stringnumber,然而值又是 nullundefined,这种状况是咱们不心愿产生的。

      let str:string = null;
      let nums:number = undefined;
      
      // 上面都会报错,因为束缚了是 string 和 number,然而值又是 null 和 undefined
      str.toLocaleUpperCase();
      nums.toString();

    👉 解决方案:

    tsconfi.json 配置文件中加上:"strictNullChecks": true之后能够取得更加严格的空类型查看,nullundefined 就不能赋值给其它类型了,只能赋值给本身

3. 其它罕用类型

  • 联结类型:多种类型任选其一

    当一个变量既能够为 字符串 又能够为 undefined 的时候就能够应用 联结类型 ,它能够配合应用 类型爱护 进行判断

    📢 类型爱护:当对某个变量进行类型判断之后,在判断的语句中便能够确定它的确切类型,tyoeof 能够触发类型爱护,然而它只能触发简略根本的类型爱护,简单类型是没有方法触发的

    let user:string | undefined;
    
    if(typeof user === "string"){// 类型爱护,当进入这个判断,TS 肯定会晓得,此时 user 肯定是字符串}
  • viod 类型:通常用于束缚函数返回值,示意该函数没有任何返回

    viodJs 也是有的,示意运算一个表达式之后返回 undefined,但在 TS 意思是不同的,通常用于束缚函数返回值,示意该函数没有任何返回

    function user():void{console.log("法医");
    }

    当然不束缚也是能够的,因为会 类型推导 进去

  • never 类型:通常用于束缚函数返回值,示意该函数永远不可能完结

    function thorwError(msg:string) {throw new Error(msg)
    }

    这个函数的 类型推导 是有问题的,推导的类型是 viod,因为它永远不会完结,类型应该是never 而不是viod,所以须要手动更改

      function thorwError(msg:string):never {throw new Error(msg)
      }

    因为是永远不会完结,所以,上面的 log 函数无奈执行,无法访问代码

    还有一种状况也是永远不会完结,须要手动束缚

  • 字面量类型:应用一个 进行束缚,而不是 类型 束缚

    // 示意从此以后,变量 name 只能是“法医”,别的就会报错
    let name:"法医";

    个别咱们能够用字面量类型对性别或者对象中的属性进行束缚:

    // 对 gender 变量进行束缚,只能是男或女,其它不行
    let gender :"男" | "女";
    
    // 对 users 对象中的 name 和 age 属性别离束缚为字符串和数字,下次给 users 赋值的时候,只能蕴含 name 和 age
    let users:{
        name:string
        age:number
    }
  • 元组类型(Tuple):用的不多,理解一下就能够了,示意固定长度的数组,并且数组中的每一项类型确定

    // 定义了一个变量为 tupleType 的数组,这个数组只能有两项,并且第一个必须为字符串,第二个必须为数字
    let tupleType:[string,number];
    
    // 第一项必须为字符串,第二项必须为数字,只能有两项,否则报错
    tupleType = ["法医",5];
  • any 类型:any 类型能够绕过类型查看,因而 any 类型能够赋值给任意类型,但必定是有隐患的,因为它无奈应用 TS 提供的爱护机制,所以不倡议随便的应用 any 类型,为了解决 any 带来的问题,TS3.0引入了 unknown 类型

4. 类型别名

给已知的类型起个新的名字,避免反复书写一些代码

type Gender = "男" | "女";
type user = {
    name:string
    age:number
    gender:Gender
}

function getUser(g:Gender) {//...}

5. 函数的相干束缚

  • 函数重载

先看一个函数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 必须是雷同的类型")
}

函数自身没有什么问题,问题就产生在函数调用的过程中,当咱们代码写多了当前,咱们兴许会失误传递不同的类型作为参数,更可怕的是如果参数是函数的返回后果,那就更蒙了,因而,在函数的调用过程中最好通知调用函数,要么都是数字类型,要么都是字符串类型。

从逻辑上来说,都是数字的话返回的后果就是数字类型,都是字符串的话返回的后果就是字符串类型,然而 result 的类型是 string | number,上图能够清晰看到,这种状况,前面就没有方法应用result 变量了,因为明明晓得都是数字返回的后果肯定是数字类型,都是字符串返回的肯定是字符串类型。意味着代码提醒中不会呈现所有数字领有的办法或者所有字符串所领有的办法,只会提醒数字和字符串独特领有的办法——toStringvalueOf 如下图:

👉 解决方案:

加上上面两句代码,这两句代码相当于通知 TS combine 函数 只能有两种状况,一种是两个数字返回数字,另一种是两个字符串返回字符串,这两句代码就叫 函数重载

📢 函数重载:在函数实现之前,对函数调用的多种状况进行申明。

// 加上这两句代码
/**
 * 失去 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("b","n");

应用函数重载之后,当调用函数的时候只能传两个数字或者两个字符串,否则会报错,再来看看成果:

  • 可选参数

📢 可选参数:能够在某些参数名前面加上 号,示意该参数能够不必传递。可选参数必须要在参数列表的开端

当形参为三个,调用函数却传了两个,就会报错,TS 是很严格的,不容许参数数量不匹配。假如第三个参数能够不传递,加个 号示意是可选参数

退出移动版