8.7 KiB
ts最大的意义就是避免你错写,漏写,能基本上屏蔽掉你的第几错误。
应用场景:
- 编写一些公用方法和全局配置对象,用于提醒使用者别传错参数。如:
API
请求参数对象param
的类型声明,规范参数和响应结果result
的类型限制。- 编写组件的时候用于提示使用者有没有写错
props
。
初识TypeScript
Typed JavaScript at Any Scale,添加了类型系统的JavaScript,适用于任何规模的项目。
ts 是 js的超级,包含js的所有元素,能运行js代码,支持ES语法,是一种开元、跨平台的编程语言。
编译器编译为js代码,完全兼容js代码,主要提供了类型系统和对 ES6 的支持,相当于静态类型检查器。
TypeScript是静态类型
类型系统按照【类型检查的时机】来分类:
- 动态类型是指在运行时才会进行类型检查
- 静态类型是指编译阶段就能确定每个变量的类型
类型检查,当检查到调用的是不属于该对象的方法时就会报错,如:1.split()
类型推论,当变量没有声明类型时,也能在变量初始化时自动推论出它的类型。
TypeScript是弱类型
类型系统按照【是否允许隐式类型转换】来区分,可以分为强类型和弱类型。
// 运行时数字1会被隐式类型转换为字符串’1‘,加号被是别为字符串拼接
console.log(1+'1');
TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性,所以它们都是弱类型。
安装TypeScript
// 安装
npm install -g typescript
// 查看版本
tsc -v
安装完后,可以在任何地方执行tsc
命令。
// 手动编译,xxx.ts文件
tsc xxx.ts
VS Code自动编译
tsc --init
生成tsconfig.json
配置文件;- 修改配置文件:
target
、outDir
、strict
- 启动监视任务:终端=》允许任务=》监视
tsconfig.json
基础
类型声明 : 在定义变量时,用:
加类型的形式。变量只能存储指定类型的值。
let num:number = 11;
原始数据类型
原始数据类型:number、string、boolean、null、undefined、Symbol(ES6)、BigInt(ES10)
undefined/null可以作为其他类型的子类型赋值给其他类型,可以理解成面向对象的多态,向上转型:
let num:number = null; ==> let 变量名:父类 = 子类型的值
任意值
任意值:any,当变量定义的时候只有声明没有赋值的情况。
let abc; ==> let abc:any;
空类型
空类型:void,表示没有任何返回值的函数。
function fun1():void{
console.log(123);
}
类型推论
类型推论(Type Inference):没有明确的指定类型,有赋值。
// 定义变量时,直接赋值,则定义类型为对应的类型,会根据赋值的类型推断变量的类型
let ac = 123;
// ac = 'w';//报错
联合类型
联合类型(Union Types):标识取值可以为多种类型中的一种。使用|
分隔每种类型。
let f:boolean|number|string = true;
f=123;//再次赋值,走类型推断,给变量定义一个类型,就可以只用对应类型的属性和方法。
访问联合类型的属性或方法只能访问共有的属性和方法。
对象的类型
对象的类型-接口:接口(interfaces)定义了对象的形状
,是对象行为的抽象,具体的行为有类(classes)去实现(implement)。可以理解成一中约束。
// -----------对象类型-------------
// object 表示非原始类型,除了number、string、boolean之外的类型
let obj:object={};
// obj = 123;//报错
// obj = '';//报错
obj = null;
obj = undefined;
obj = [];
obj = new String();//不通过字面量的方式,采用new的方式定义。
obj = String
// -------------接口--------------
interface Person{
name:string,
age:number
}
// 定义对象属性不能多也不能少。赋值的时候,变量的形状必须和接口的形状保持一致。
let tom:Person ={
name:'',
age:22
}
// 可选属性,使用?。定义的对象可以不添加age
interface Person{
name:string;
age?:number;
}
// 只读属性,使用readonly定义,只能在创建的时候被赋值
interface Person {
readonly id: number;
name: string;
age?: number;
}
// 任意属性,使用 [propName: string] 定义了任意属性取 string 类型的值。
interface Person{
name:string;
age:number;
属性名([propName: string]): any;
}
// 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
// 即:propName定义为string,那对象中的其他属性类型都必须是它的类型的子集(string/null/undefined)
一个接口中只能定义**【一个】**任意属性。如果接口中有多个类型的属性,则可以在任意属性中使用联合类型:
interface Person {
name: string;
age?: number;
[propName: string]: string | number;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
数组类型
数组类型:多种定义方式
//使用「类型 + 方括号」来表示数组,项中不允许出现其他的类型
let arr1:[]=[];
let arr2:number[]=[212,212,3];
let newArr:any[]=[1,2,3,'',true];//谨慎使用any
let fibonacci: number[] = [1, 1, 2, 3, 5];
//数组泛型(Array Generic):使用 Array<类型> 的方式。
let fibonacci: Array<number> = [1, 1, 2, 3, 5];
// 用接口表示数组(不常用),[1,2,3,4] arr[0]==>obj['name']
interface NumberArray {
[index: number]: number;//任意属性,index表示数组中的下标
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
函数类型
-
函数声明
// ts,函数声明,命名函数 function add(a:number,bnumber):number{ return a+b; }
-
函数表达式
// ts,函数表达式,匿名函数 let sum = function(a:string,bstring):boolean{ return a.search(b) !== -1; } // ts,完整写法 // 在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。 let add:(a:number,b:number)=>number = function(a:number,b:number):number{ return a.search(b) !== -1; }
-
接口定义函数的形状
interface ISearchFunc{ // (参数:类型,...):返回值类型 (a;string,b:string):boolean; } const fun1:ISearchFunc = function(a:string,bstring):boolean{ return a.search(b) !== -1; } console.log(fun1('123','1'));
可选参数|默认参数|剩余参数
// 可选参数
// 使用?放到参数前面,但可选参数的位置不能位于必选参数前
let getName = function(x:string,y?:string):string{
return x+y;
}
console.log(getName('hello '));
// 默认参数
// 直接在参数类型后面赋值
let getName = function(x:string='Hello ',y?:string):string{
return x+y;
}
console.log(getName('hello '));
//剩余参数
// 使用 ...rest 语法接受,下列示例:使用args数组接收
function fn(x:string,y:string,...agrs:number[]){
}
fn('','',1,2,3,4,5)
函数重载
可以理解成:函数名相同,形参不同的多个函数
类型断言
类型断言,可以手动指定一种类型。
应用场景:
- 使用联合类型时
- window上挂载变量时
- 将any类型断言为一个具体的类型
两种方式:
-
变量 as 类型
function getLength(x:string|number):number{ if((x as string).length){ return (x as string).length; }else{ return x.toString().length } }
-
<类型> 变量
function getLength(x:string|number):number{ if((<string>x).length){ return (<string>x).length; }else{ return x.toString().length } }
在window上添加全局变量
// 将任何一个类型断言为any,any类型是访问任何属性和方法的
(window as any).a = 11;
它(any)极有可能掩盖了真正的类型错误,所以如果不是非常确定就不要使用
as any
将any类型断言为一个具体的类型
function abc(x:any,y:any):any{
return x+y;
}
let a = abc(1,2) as number;//a-->数值类型
类型断言的特性:
- 联合类型可以被断言为其中一个类型
- 父类可以被断言为子类
- 任何类型都可以被断言为any
- any可以被断言为任何类型