类型推导 typescript-TypeScript 基础知识 – 基本类型检测

为什么使用 TypeScript?

JavaScript设计之初只是为了补充Java,对浏览器做一些小疗效,而不是针对小型复杂的项目。 JS本身也有很多缺陷。 至于为什么要用TS,朋友们可以看这篇文章:我们为什么要学习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)是否是在调用函数。 有可能中途改了测试,然后调用函数就报错。

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

复制

但这些情况在TS里是绝对不允许的,“哟哟,奇克Nao,我是TS,鸭子不允许”

typescript类型定义_类型推导 typescript_typescript介绍

因为TS知道函数测试和调用函数测试是同一个东西,所以有一个神奇的疗效——当函数需要重命名时,双击函数测试按F2,函数名就变了,调用函数名后面跟着改了,之所以能达到这样的疗效是因为TS有严格的类型检测系统,它知道调用函数的测试使用了测试函数,三者之间的关系就建立起来了

不仅如此,还有一个疗效:当我们点击调用函数并按F12时,它会跳转到定义的函数位置,

为了让我们写更少的代码,在使用TS进行约束时,TS可以在很多场景下完成类型推断

举个栗子:

当我们去掉函数返回值约束后,从提示中仍然可以发现返回值是number。 这是因为我们将参数约束为number,而number与number相减仍然是一个数字,所以函数最后会返回number并将其赋值给变量。 result和TS会智能检测到函数返回的结果是数字,所以结果类型也是数字,所以我们只需要在参数位置添加类型约束即可。 TS到处都有类型检测类型推导 typescript,是不是很牛逼?

紧急通知:翠花小姐来了

翠花老师问了一个问题:我怎么知道这种推理什么时候成功,什么时候失败?

回答:

有一个小方法,当我们听到变量或者函数的参数中出现三个点的时候,这三个点就是在提醒我:小心,我真的做不到,也就是说没有对处的类型进行推导present ,可以用任意类型表示,那么需要自动限制,

any:表示任意类型,对于该类型,TS不进行类型检测

看到这里,我想你已经知道TS有一个特别强大的类型检测系统,所以有一个小问题

一个灵魂问题:手机号码应该定义为一个数字还是一串数字?朋友们,你可以先想一想,然后看一下。

看一看

如何区分数字串和数字,关键是怎么读? 如果以数字形式读取,则为数字,否则为字符串。

帅哥一听,说道:“哎哟,你不想再交好运了,就耽误了你的好运。” 他赶紧拿出手机记事本,小心翼翼地别写错了,131、5258、3720。我们一般都是这么读的,没有人读。 13.15252583722,姑娘要听,滚出去~~你活该单身!

typescript介绍_typescript类型定义_类型推导 typescript

2. 基本类型

注意第一个字母要大写

数量: 数量,

let figure:number = 6;

复制

字符串:字符串

let user:string = "法医";

复制

布尔值:布尔值

let fake:boolean = false;

复制

数组:数组

:number[] 好像是一个句子糖。 真正的方法是下面的第二种。 这两种方式都可以约束字段。 这取决于个人喜好。 推荐使用第一个,因为尖括号代表react中的组件,数组可能会造成冲突

let arr:number[] = [1,2,3];
let arr:Array = [1,2,3];

复制

对象:对象

对象约束不是很常用,因为对象约束不是很强,它只能约束一个对象,而不能约束对象上的内容,但有时也会使用

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

复制

空且未定义

需要强调的是 null 和 undefined。 Null 和 undefined 是所有其他类型的子类型。 它们可以作为其他类型的参数,但会有隐患。 下面的方法会报错,因为约束是字符串和数字,但值又是null且未定义,这是我们不希望发生的。

let str:string = null;
let nums:number = undefined;
//下面都会报错,由于约束了是string和number,但是值又是null和undefined
str.toLocaleUpperCase();
nums.toString();

复制

解决方案:

添加: "strictNullChecks": true 到 tsconfi.json 配置文件以获得更严格的 null 类型检查。 null 和 undefined 不能用作其他形式的参数。

3.其他常用类型

接头类型:三种类型中选择一种

当变量既可以是字符串又可以是undefined时,可以使用联合类型,可以通过类型保护来区分

类型保护:对变量进行类型判断后,可以在判断语句中确定其确切类型。 tyoeof 可以触发类型保护,但是只能触发简单和基本类型保护,没有办法触发复杂类型

let user:string | undefined;
if(typeof user === "string"){
    //类型保护,当进入这个判断,TS一定会知道,此时user一定是字符串
}

复制

viod类型:通常用于约束函数的返回值,表示该函数没有返回值

viod在Js中也有,意思是计算表达式后返回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)
}

复制

由于它永远不会结束,因此以下日志函数很难执行并且无法访问代码

还有一种情况永远不会结束,需要自动约束

文字类型:用值而不是类型进行约束

//表示从此以后,变量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 type:any类型可以绕过类型检测,因此any类型可以作为任何类型的形参,但是一定存在隐患,因为它未能使用TS提供的保护机制,所以不建议使用any类型随便,为了解决any引起的问题,TS3.0引入了未知类型

4. 类型别名

给已知类型一个新名称以防止重复某些代码

typescript介绍_typescript类型定义_类型推导 typescript

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必须是相同的类型")
}

复制

函数本身并没有什么问题。 问题发生在函数调用过程中。 当我们编写太多代码时,我们可能会错误地传递不同的类型作为参数。 更可怕的是,如果参数是函数的返回结果,那么就会很混乱,因此,最好在函数调用过程中告诉调用函数,它要么是数字类型,要么是字符串类型。

从逻辑上讲,如果都是数字,则返回结果是数值类型,如果都是字符串,则返回结果是字符串类型。 但是,结果的类型是 string | 数量,如上图所示。 在这种情况下,下面就没有办法使用result变量了,因为很显然,所有数字返回的结果都必须是数值类型,而所有字符串返回的结果必须是字符串类型。 意思是所有数字拥有的方法或者字符串拥有的所有方法都不会出现在代码提示中,而只会提示数字和字符串拥有的方法——toString和valueOf如下图所示:

解决方案:

添加下面两行代码,这两行代码相当于告诉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");

复制

使用函数重载后,调用函数时只能传递两个数字或者两个字符串,否则会报错。

可选参数:前面可以有单独的参数名称吗? 否,表示该参数不能传递。可选参数必须在参数列表的末尾

当数组数量为3个类型推导 typescript,但有2个传递给调用函数时,会报错。 TS非常严格,不允许参数数量匹配。 假设第三个参数不能传,加一个?数字表示是可选参数

结论

写完,又是凌晨了,TS基础知识的基本类型检测就结束了。 本来想把TS的基础部分整理成4D文字分享给大家,但是觉得太长了,看不懂,所以会逐步更新。 有疑问可以留言,朋友点赞关注再走! ~,我会更有动力,晚安!