Typescript
一:简介
TypeScirpt是JavaScript的超集,为Javascript的生态增加了类型机制,并最终将代码编译为纯粹的Javascript代码。
-
全局安装typeScript
npm install -g typescript在项目中执行以下命令,表示项目初始化,会生成tsconfig.json文件
tsc -init -
在项目中新建test.ts
let name = "张三";//根据初始化的赋值,可以推导出变量的类型。以后这个变量的类型是不可修改的。 //name = 1;//类型不一致,报错。 const userName = '张三';//常量不可以修改,所以它的值就是它的类型
3.执行命令:tsc 文件名,编译ts文件,编译后会生成一个js文件。也可以通过如下图的方式,此方式生成js文件并实时监听
tsc test.ts
tsc -p tsconfig.json --watch //如果下图功能
二:变量类型
-
原始类型 ts的原始类型就是js的基础数据类型:string,number,boolean,null, undefined,symbol
let str:string = "11"; let num:number = 1; let bol:boolean = true; let nul:null = null; let und:undefined = undefined; let sy:symbol = Symbol('123');//Symbol('123')!= Symbol('123');symbol是每次都是新的内存空间//在函数中如果没有返回值,函数类型就是void function a():void{}
-
非原始类型:object Object {};其中Object等同于{}
//object 不包含基础数据类型 let obj:object = {a:1}; let arr:object = [1,2]; //Object 包含基础数据类型 let obj1:Object = {a:1}; let arr1:Object = [1,2]; let str1:Object = '123'; let num1:Object = 1; let bol1:Object = true; -
数组类型
let arr1:number[]=[1,2,3]; //泛型,类型参数化 let arr2:Array<number>=[1,2,3]; //元组,位置定死 let arr3:[number, number, string, boolean] = [1,2,'3',true]; -
联合类型'|'
let str:number|string=1; str='1'; let num:1|'2'=1; num = "2"; let obj:{a:1}|{b:'2'} = {a:1}; obj = {b:'2'}; obj = {a:1,b:'2'}; let obj1:{a:number}|{b:string} = {a:3};//表示有a属性或者有b属性,或者都有 obj1 = {b:'张三'}; obj1 = {a:2,b:'李四'}; let arr:(number|string)[] = [1,'2','1']; -
交叉类型'&'
let obj:{a:number}&{b:string,c:number} = {a:3,b:'1',c:1};//abc三个属性都必须有 -
any与unknown的区别
//不推荐使用any,any绕过了类型校验 let a:any = 1; a = '1'; a = [1,2]; a = {c:1}; a.toFixed(2);//不报错,绕过了校验 let b:unknown = 1; b = '1'; b = [1,2]; b = {c:1}; b.toFixed(2);//报错,有做类型校验 -
接口类型interface,用来自定义类型
//定义接口类型--给对象用 interface Person{ //属性名:值的类型 name:string, age:number, address:string } //接口定义的属性都必须有 let obj:Person = { name:'张三', age:19, address:'江苏' }; //定义接口类型--给数组用 interface ArrInter{ //[idx:number]下标类型:值的类型 [idx:number]:number|string } let arr:ArrInter = [1,2, '3']; //定义接口类型--给函数用 interface FunInter{ //形参及参数:值的类型 (num:number):void } let fun:FunInter = (num:number)=>{}
8.接口继承extends
//定义接口类型
interface Person{
//属性名:值的类型
name:string,
age:number,
address:string
//[idx:string]:number|string
}
interface Hobby{
hobboyName:string,
hobboyLevel:number
}
//接口继承,具有父接口的所有属性
interface User extends Person,Hobby{
enLevel:number;
}
//属性都要有
let obj:User = {
enLevel:2,
name:'张三',
age:18,
address:'112',
hobboyLevel:12,
hobboyName:'12'
}
9.接口同名
//接口可以同名,相当于属性合并
interface Person{
//属性名:值的类型
name:string,
}
interface Person{
age:number,
address:string
}
let obj:Person = {
name:'张三',
age:18,
address:'112',
}
10.接口缺省?,只读readonly
interface Person{
readonly name:string,//readonly表示这个属性只读,不可以修改
age?:number,//?表示这个属性可以缺省,定义属性的时候可以不写
address:string
}
let obj:Person = {
name:'颤三',
// age:18,
address:'112',
}
obj.name="lisi";//报错,因为是只读属性
11.联合交叉类型
let obj:{a:string}&{b:number}|{a:number}&{ b:string}={
a:'aa',
b:1
};
obj = {
a:11,
b:'11',
}
let obj1:{a:string}&{b:number}&{h:number}|{a:number}&{b:string}&{ c:string}&{d:number}={
a:'aa',
b:1,
h:11
};
obj1 = {
a:112,
b:'1',
c:'dd',
d:1,
h:12
}
12.类型别名Type 与interface的区别是,都可以自定义类型,但是Type不能重复定义,接口可以
type BasicType = string|number;
let a:BasicType = '1';
a = 1;
//定义给对象
type ObjType = {a:string, b:number};
let obj:ObjType = {
a:'aa',
b:1
}
//定义给函数
type funType = (a:number)=>void;
let fun:funType = (a:number)=>{};
interface Person{
name:BasicType,
age:number
}
let user:Person={
name:'11',
age:10
}
user.name = 11;
//用类型别名保存接口上某个属性的值类型
type Itype = Person['age'];
let testType:Itype = 11;
13.函数
//剩余参数(...)
function fun1(a:number, b:number,...arr:number[]):number{
return a+b
}
//缺省参数(?)
function fun2(a:number, b?:number):number{
return a
}
//默认参数(=)
function fun3(a:number, b:number=1):number{
return a+b
}
function fun(a:number, b:number):number{
return a+b
}
//定义接口类型
interface Calc{
(a:number, b:number):number;
}
let funCalc:Calc = (a:number, b:number)=>{
return a+b;
}
//定义给函数
type funType = (a:number, b:number)=>number;
let fun1:funType = (a:number, b:number)=>{return a+b};
//////函数作为对象的属性
//接口定义
interface ObjInt{
fun:Calc
}
let obj:ObjInt = {
fun:(a:number, b:number) => {
return a+1
}
}
obj.fun(1,2);
//类型别名
type objType = {fun:funType}
let obj2:objType = {
fun:(a:number, b:number) => {
return b+2
}
}
obj2.fun(1,2);
14.Promise
//定义类型
interface PromiseInter{
data:string,
code:number,
msg:string
}
let fun:Promise<PromiseInter> = new Promise((resolve,reject) => {
resolve({
data:'',
code:0,
msg:''
})
})
fun.then(res => {
console.log(res.data)
})
15.this的使用 window就是Window这个类型的对象
/////在全局上,给Window接口扩展属性
//接口可以同名
interface Window{
title:string;
}
function Person(this:Window, name:string){
//在ts中,需要指明this的指向,在函数的第一个形参中注明。Window中没有title属性,需要自己扩展
this.title = name;
}
window.Person('tt');
//this非window指向
interface ObjInt{
title:string,
Person:(n:string)=> void
}
let obj:ObjInt = {
title:'标题',
Person:(name:string)=> {}
}
function Person(this:ObjInt, name:string){
//在ts中,需要指明this的指向,在函数的第一个形参中注明。Window中没有title属性,需要自己扩展
this.title = this.title+name;
}
obj.Person = Person;
obj.Person('tt');
16.枚举,用来列举数据用的。
enum StatusCode{
success=200,
error=500
}
let code:number = 200;
if(code == StatusCode.success){
console.log('成功')
}else if(code == StatusCode.error){
console.log('失败')
}else{
console.log('其他')
}
enum StatusCode1{
success,//0
error=500,
fail//501
}
17.泛型,泛型约束extends
//泛型-类型的形参,T是一个标识符,可以自定义,T表示某种类型。类型参数化
function fun<T>(n:T):T{
return n
}
function fun1<A>(n:A):A{
return n
}
fun<number>(1);
fun1<number>(2);
fun1<boolean>(false);
function fun2<A,B>(n:A,m:B):A{
return n
}
fun2<number, string>(1,'2')
//--------泛型在类型别名和接口上的应用
type StrOrNum = string|number;
interface Person<T,C,A,G>{
name:T;
age:A,
getName:(name:C)=>G;
}
let obj:Person<string, string, StrOrNum,void> = {
name:'zhanshan',
age:'2',
getName:()=>{}
}
function getNa(this:Person<string, string, StrOrNum, void>, name:string) {
this.name = name;
}
obj.getName = getNa;
//--------可以设置默认类型
interface Person1<T=string,C,A,G>{
name:T;
age:A,
getName:(name:C)=>G;
}
//--------约束,T只能是string或者number类型
interface Person2<T extends StrOrNum,C,A,G>{
name:T;
age:A,
getName:(name:C)=>G;
}
18.类
//定义类的同时,生成一个相同名称的接口
class Person{
//定义属性
myName:string;
//默认值
myAge:number = 1;
constructor(n:string){
this.myName = n;
}
getAge(){
return this.myAge;
}
}
let person = new Person('张三');
console.log(person.myName);
console.log(person.getAge())
//相当于接口
// interface PersonInt{
// //定义属性
// myName:string;
// //默认值
// myAge:number;
// getAge:() => number;
// }
let obj:Person={
myName:'11',
myAge:10,
getAge:()=>{
return 333
}
}
//--------类的继承
class Stu extends Person{
snum:string;
constructor(name:string, num:string){
super(name);//调用回父类的constructor,并把参数传进去
this.snum =num;
}
getAge(){//与父类方法名相同,重写
return 100
}
}
let stu = new Stu('aa','11');
//--------类的修饰符
//类中定义的属性,默认修饰符就是public,public修饰的属性和方法在类的内部、类的外部和子类也可以访问
//protected受保护,在类的内部和子类中都可以访问,类的外部不可以访问
//private私有,在类的内部可以访问,子类和类的外部不可访问
class Dog{
public name:string;
//readonly 设置属性只读
// public readonly name:string;
protected age:number=10;
private type:string ='泰迪';
constructor(n:string){
this.name = n;
}
public getName(){
return this.name;
}
}
class Anima extends Dog{
//静态属性static
static title:string = "测试";//静态属性/成员,是给类用的
constructor(n:string){
super(n);
}
getAge(){//可以访问
return this.age
}
// getType(){//报错,不可以访问
// return this.type
// }
}
let anima = new Anima('111');
// console.log(anima.age);//报错,不能访问
// console.log(anima.type);//报错,不能访问
Anima.title = '111'
19.抽象类和接口
//抽象类是普通类的描述,指定类的规范,给类继承。继承之后,普通类里面就必须定义抽象类里面的抽象方法和属性
//抽象类中的普通方法直接继承,在普通类中可以不用实现
abstract class Person{
//抽象属性
abstract myName:string;
//抽象方法
abstract getName():string;
getAge(){
return '11'
}
}
class Student extends Person{
myName:string = '张三';
getName(){
return 'test'
};
}
let student = new Student();
console.log(student.getName());
console.log(student.getAge());
//抽象类不能被实例化
// let tea = new Person();//报错
//定义接口给类用
interface PersonInter{
myName:string;
getName:() => string;
}
class Teacher implements PersonInter{
myName:string = "";
getName() {
return 'abc'
}
}
20.keyof,in,typeof
//定义接口给类用
interface PersonInter{
myName:string;
age:number;
[idx:number]:string|number;//[idx:string]:string|number;
}
//keyof
type typePerson = keyof PersonInter;//'myName' | 'age'|number
let type:typePerson = 'myName';
type = 1;
//in
type StrOrNumber = string|number;
type TypeObj = {
[k in StrOrNumber]:string
}
let obj:TypeObj = {
1:'11',
name:'ddd'
}
//typeof,提取变量或者对象的类型
let str = '22';
type StrType = typeof str;
let obj1 = {
name:'1',
age:10
}
type ObjType = typeof obj1;
let obj2:ObjType = {
name:'test',
age:100
}
21.extends和类型推断infer
//extends
type FuType<P> = P extends string|number?P[]:P;
let num:FuType<number> = [1,2];
let bln:FuType<boolean> = false;
//infer类型推断
type ObjType<T> = T extends {a:infer A, b:infer B}?[A,B]:null;
let obj:ObjType<string> = null;
let obj1:ObjType<{a:string, b:number}> = ['1',1];