typescript学习总结
qq学习讨论群:910316886
<!-- 安装: npm i -g typescript tsc -v (查看typescript版本) 将ts编译为js,在终端输入命令,tsc hello.ts 执行js代码:在终端输入命令,node hello.js --> <!-- 简化执行步骤: tsc --init 初始化tsconfig.json文件 npm i -g ts-node ts-node hello.ts --> <!-- 数组类型的两种写法 let numbers:number[]=[1,2,3] let numbers2:Array<number>=[2,3,45,5] let strings:Array<string>=['a','b','c'] let b:boolen[]=[false,true,false] 既有数组又有字符串的类型(联合类型:由两个或多个类型组成的类型) let arr:(number|string)[]=[1,'a',3,'b']; --> <!-- 类型别名 CustomArray这个是自己定义的任意合法的变量名 创建类型别名后,直接使用该类型别名作为变量的类型注释即可 type CustomArray = (number|string)[] let arr1:CustomArray=[1,'a',2,'ggg'] let arr2:CustomArray=[3,'o',9,'sddsad'] --> <!-- 函数类型:函数参数和返回值的类型 为函数指定类型的两种方式: 1 单独指定参数,返回值的类型 function add(num1:number,num2:number):number{ return num1+num2; } add(1,2); //必须传参数 2 同时指定参数、返回值的类型(只适用于函数表达式) const add:(num1:number,num2:number)=>number=(num1,num2)=>{ return num1+num2; } 3 如果函数没有返回值,那么,函数返回值的类型为:void function greet(name:string):void{ console.log('hello',name) } greet('susu') 4 可选参数:在可传可不传的参数名称后面加?(问号) 可选参数只能出现在参数列表的最后,也就是说可选参数后面不能再出现必选参数 function mySlice(start?:number,end?:number):void{ console.log('起始索引:',start,'结束索引:',end) } mySlice(1,2) mySlice(1) mySlice() --> <!-- 对象类型 let person:{name:string;age:number;sayHi():void}={ name:'susu', age:18, sayHi(){} } sayHi():void是一个方法,表示没有返回值; 换行,可以把分号去掉 let person:{ name:string age:number sayHi():void }={ name:'susu', age:18, sayHi(){} } --> <!-- 接口 当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到复用的目的。 1 使用interface关键字来声明接口 2 接口名称(可以是任意合法的变量名称) 3 声明接口后,直接使用接口名称作为变量的类型 4 因为每一行只有一个属性类型,因此,属性类型后没有;(分号) interface IPerson{ name:string age:number sayHi():void } let person:IPerson={ name:'susu', age:16, sayHi(){} } --> <!-- interface(接口)和type(类型别名)的对比 相同点:都可以给对象指定类型 不同点: 接口:只能为对象指定类型 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名 interface IPerson{ name:string age:number sayHai():void } type IPerson={ name:string age:number sayHi():void } --> <!-- extends interface Point2D {x:number,y:number} interface Point3D extends Point2D {z:number} --> <!-- 元组: 它确切的知道包含多少个元素,以及特定索引对应的类型 let position:[number,number]=[39.54,116.23] --> <!-- 类型推论: 声明变量并立即初始化值,此时,可以省略类型注释 能省略类型注释的地方就省略 决定函数返回值也可以进行推论 类型断言,通过as关键字指定一个更加具体的类型 console.dir($0)打印结果的最后就可以看到元素的类型 --> <!-- 字面量类型 一般用在一组可明确的可选值类型 function changeDirection(direction:'up'|'down'| 'left'| 'right'){ } changeDirection('up') --> <!-- 枚举 enum Direction {Up,Down,Left,Right} 默认0,1,2,3 function changeDirection(direction:Direction){ console.log(direction) } changeDirection(Direction.Up) 枚举成员初始化值 enum Direction {Up=10,Down,Left,Right} 10,11,,12,13 enum Direction {Up=10,Down=12,Left=14,Right=16} enum Direction {Up='UP',Down='DOWN',Left='LEFT',Right='RIGHT'} --> <!-- class类 class Person{ age:number, gender='男' constructor(age:number,gender:string) {//构造函数不需要返回值 this.age = age this.gender = gender } } const p = new Person(15,'女') console.log( p.age, p.gender) --> <!-- interface Singble{ sing():void name:sting } class Person implements Singable{ name='susu' sing(){ console.log('哈哈哈') } } 解释:implements实现接口 1 通过implements 关键字让class实现接口 2 Person类实现接口singable意味着,Person类中必须提供Singable接口中的方法和属性 --> <!-- 可见性修饰符 1 public 2 protected 仅对其声明所在类和子类中可见 3 private 表示私有的,只在当前类中可见;对其实例对象以及子类也是不可见的 4 readonly 表示只读,用来防止在构造函数之外对属性进行赋值,也不可以用于方法 (需要指定类型,不然就变成字面量了;接口和普通的对象中也可以使用readonly;只读不可赋值) --> <!-- 类和接口的兼容性:成员多的可以复制给成员少的 函数兼容性(参数少的可以赋值给多的) --> <!-- 交叉类型:组合多个类型为一个类型 interface Person {name:string} interface Contact {phone:string} type PersonDetail = Person & Contact let obj:PersonDetail={ name:'jack', phone:'1333' } --> <!-- 泛型 泛型在保证类型安全的同时,可以让函数和不同类型的数据一起使用 function id<Type>(value:Type):Type{return value} const num=id<number>(10) 也可以简写成 const num=id(10) --> <!-- 泛型类 class GenericNumber<Numype>{ defaultValue:NumType add:(x:NumType,y:NumType)=>NumType } const myNum = new GenericNumber<number>() myNum.defaultValue = 0 --> <!-- 泛型工具类型 1 Partial创建一个新的类型,并且属性是可选的 interface Props{ id:string children:number[] } type PartialProps = Partial<Props> let p1:Props={ id:'', children:[1] } let PartialProps{ id:'' } 2 Readonly 所有属性都是可读的 interface Props{ id:string children:number[] } type PartialProps = Readonly<Props> let p1:PartialProps{ id:'222', children:[1,2,3] } p1.id='2'//报错 3 Pick Pick<Type,keys>从Type中选择一个属性来构造新类型 interface Props{ id:string children:number[], title:string } type PickProps = Pick<Props,'id'|'title'> 4 Record<Key,Type>构造一个对象类型,属性键为keys,属性类型为Type type RecordObj=Record<'a'|'b'|'c',string[]> let obj:RecordObj={ a:['1'], b:['2'], c:['3'] } --> <!-- 索引签名类型 interface AnyObject{ [key:string]:number key是一个占位符,可以换成任意合法的变量名 } let obj:AnyObject{ a:1, b:2, c:3 } interface MyArray<Type>{ [n:number]:Type } let arr:MyArray<number>=[1,2,3,4] --> <!-- 映射类型:基于旧类型,创建新类型(对象类型) type PropKeys='x'|'y'|'z' type Type1 = {x:number,y:number,z:number} type Type2 = {[key in PropKeys]:number} type Type3 = {[key in keyof Type1]:number} 索引查询类型 type Props = {x:number,y:number,z:number} type Prop = Props['x'] type Prop = Props['x'|'y'] type Prop = Props[keyof Props] 拿到所有索引 --> <!-- 类型声明文件 为已存在的js库,提供类型信息 包含内置的ts类型声明文件,库自带的类型声明文件以及github中DefinitedTyped TS官方文档中提供了一个页面,用来查询@types/*库的类型,在工具里 declare关键字:用于类型声明,为其它地方,已存在的变量声明类型,而不是创建一个新的变量 --> <!-- type a = 'a'|'b'|'c' type b = 'b'|'c' //剔除 type Atype = Exclude<a,b> let aDate:Atype='a' //包含 type Btype = Extract<a,b> let aDate:Atype='b' //或者c --> <!-- 命名空间:内部模块,主要用于组织代码,避免命名冲突 export namespace A{ interface Animal{ name:string } export class Dog implements Animal{ name:string constructor(theName:string){ this.name = theName } eat(){ console.log(`${this.name}在跑。`) } } } export namespace B{ interface Animal{ name:string } export class Cat implements Animal{ name:string constructor(theName:string){ this.name = theName } eat(){ console.log(`${this.name}在玩耍。`) } } } let dog= new A.Dog('小狗') dog.eat() let cat =new B.Cat('小猫') cat.eat(); import {A} from '文件名' --> <!-- 类装饰器 方法一:普通装饰器,没办法传参 function logClass(params:any){ console.log(params) params.prototype.apiUrl = '动态扩展属性' params.prototype.run=function(){ console.log('我在跑步') } } @logClass //普通装饰器,没办法传参 class HttpClint{ constructor(){ } getDate(){ console.log('获取数据') } } let http = new HttpClint() http.run() 方法二:类装饰器,可传参 function logClass(params:any){ return function(traget:any){ console.log(target) console.log(params) traget.prototype.apiUrl = params } } @logClass('hello') class HttpClint{ constructor(){ } getDate(){ console.log('获取数据') } } let http2 = new HttpClint(); console.log(http.apiUrl) 修改类中的属性和方法 function logClass(target:any){ console.log(target) return class extends target{ apiUrl:any='我是修改后的数据' getDate(){ this.apiUrl=this.apiUrl+'......' console.log(this.apiUrl) } } } function logProperty(params:any){ return function(target:any,attr:any){ console.log(target,attr) target.attr = params } } @logClass('hello') class HttpClint{ @logProperty('http://itying.com') public apiUrl:string |undefined; constructor(){ this.apiUrl = '我是构造函数里的apiUrl' } getDate(){ console.log(this.apiUrl) } } let http2 = new HttpClint(); console.log(http2.apiUrl) htttp2.getDate() --> <!-- ///<reference path='路径'> 最外层的namesapce不能导出,不然会报错 --> <!-- infer关键字 --> <!-- bight与symbol -->
标签:总结,typescript,string,--,number,学习,let,Type,id From: https://www.cnblogs.com/yaosusu/p/16946109.html