基本类型约束
TS是一个可选的静态的类型系统,没有必要一定使用ts规则
如何进行类型约束
仅需要在变量、函数的参数,函数的返回值位置加上:类型
简单的例子:
function sum1(a:number , b:number) : number{
return a + b;
}
const total: number = sum1(1,2);
-
在js中sum函数可以被更改,如改成
sum = 1,而在ts中,更改sum会报错,sum(1, 2)明确知道引用的哪一个函数,则当选中sum使用后F2改变sum的函数名字时为add时,sum(1, 2)也会自动变成add(1, 2),非常方便 -
自动推导,对于
sum函数,当指定两个参数为number类型时,会自动推导出函数类型为number。 ts在很多场景中可以完成类型推导 -
如何知道是否可以推导出类型
当变量出现三个点时,意思是类型为
any,没有明确类型,书写代码时应注意any:表示任意类型,ts不进行类型检查
小技巧:如何区分数字字符串和数字,关键看怎么读? 如果按照数字的方式读,则为数字,否则为字符串。
源代码和编译结果的差异
编译结果没有类型约束信息。运行的时候没有ts代码,输出结果为:
function sum1(a, b) {
return a + b;
}
let total = sum1(1, 2);
基本类型
- number: 数字
- string: 字符串
- boolean: 布尔
- number[]: 数组
- object: 对象
- null和undefined
ts会根据类型智能提示相关方法,智能程度待议
-
为了加深对于ts严格类型检查的印象,现有判断是否为奇数的函数,出现以下报错,请问为什么
为什么会报错呢?
ts有严格的类型检查,规定了函数类型为
boolean,则必须返回true或false -
数组约束
下面两种写法意思一样,意思是声明数字类型数组,需指定数组中的各元素类型
let array1: number[]; let array2: Array<number>;不要使用
let array1: [];,后面在字面量类型中会提到 -
null和undefined
null和undefined可以赋值给其他类型,开发时会有隐患,如
const str: string = undefined; str.toUppercase(); //因为str是string类型,会自动提示字符串方法,但是此情况会报错通过配置文件的
"strictNullChecks": true可以获得更严格的类型检查,null和undefined只能赋值给自身
其他类型
-
联合类型:多种类型各选其一 某些情况下,如用户姓名,可以为空。使用方法
const name: string : undefined = 'string'; //const name: string : undefined = undefined;此情况下使用字符串方法,智能提示消失,ts不清楚具体类型
但是,此时就体现出ts智能提示恐怖之处,加入类型判断
if(typeof name === 'string'){ //类型保护 name.toUppercase();//进入到判断中,ts已经知道name此时为string类型 }类型保护:当对某个变量进行类型判断后,在判断的语句块中便可以判断它的确切类型,typeof可以触发类型保护,但是只能触发js中基本类型的类型保护,如果是object等复杂类型则不能触发。 配合类型保护进行判断
-
void类型:通常用于约束函数返回值,表示该函数没有任何返回值
-
never类型:通常用于约束函数返回值,表示该函数永远不会结束
ts会默认以下函数为
void类型,实际上该函数应该为never类型function throwError(msg: string): never { throw new Error(msg); } function continueFunc(): never { while (true) {} } -
字面量类型:使用一个值来约束
let gender: '男' | '女'; let arr: []; //arr只能取值为空数组 let stu: { name: string; age: number; }; //对象的字面量约束,一般不使用 -
元组类型:一个固定长度的数组,并且数组中每一项类型确定
-
any类型: any类型可以绕过类型检查,因此可以赋值给任意类型(不推荐使用)。
类型别名
对一些已知的类型定义名称
type 类型名 = ...
为什么会有类型别名
当我们需要一个对象数组时,更改对象属性时,修改的地方过多,代码不美观
let user: {
name: string
age: number
gender: '男' | '女'
}
function getUSer(): {
name: string
age: number
gender: '男' | '女'
}[] {
return [];
}
当使用类型别名
type Gender = '男' | '女';
type User = {
name: string
age: number
gender: Gender
};
let user: User;
function getUsers(g: Gender): User[] {
return [];
}
函数的相关约束
先从一个简单的例子入手,两个参数,都是数字则返回相乘,都是字符串则返回字符串拼接,否则报错。
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 and b must be same');
}
const reslut = combine(3, 3); //此时result的类型信息丢失
result的类型信息丢失,按理说传入的都是数字类型,返回的也只能是数字类型,但是事实并非如此。result的信息丢失对后面书写代码带来不便。
-
函数重载:在函数实现之前,对函数调用的多种情况进行声明。
/** * return a * b * @param a * @param b */ function combine(a: number, b: number): number; /** * return 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 and b must be same'); } const reslut = combine(3, 3); //此时combine只能传入相同类型的数据,否则报错 -
可选参数:可以在某些参数名后加上?,表示可以选择,可选参数必须在参数末尾。当最后一个参数为默认值且使用时未传递,被认为可选参数。
function sum(a:number , b:number , c?:number){
if(c){
return a + b +c ;
}else {
return a + b;
}
}
- 默认参数
function sum(a:number , b:number , c?:number){
return a + b + c;
}