当前位置: 首页 > news >正文

大良做网站的公司m8wordpress主题

大良做网站的公司,m8wordpress主题,泉州网站建设选择讯呢,基于云服务器的网站开发文章目录 TypeScript入门2.编译并运行TS代码2.1.简化运行ts步骤 3.TS中的常用类型3.1.TS中的类型注解3.2.TS中的原始类型3.3.TS中的数组类型3.4.TS中的联合类型3.5.类型别名3.6.函数类型3.6.1.单独执行参数、返回值类型3.6.2.同时指定参数#xff0c;返回值类型3.6.3.函数的vo… 文章目录 TypeScript入门2.编译并运行TS代码2.1.简化运行ts步骤 3.TS中的常用类型3.1.TS中的类型注解3.2.TS中的原始类型3.3.TS中的数组类型3.4.TS中的联合类型3.5.类型别名3.6.函数类型3.6.1.单独执行参数、返回值类型3.6.2.同时指定参数返回值类型3.6.3.函数的void类型3.6.4.函数可选参数* 3.7.TS中的对象类型3.8.接口3.9.元组3.10.类型推论3.11.函数类型断言3.12.字面量类型3.13.枚举**枚举成员的值以及数字枚举**字符串枚举 3.14.any类型3.15.typeof 4.TS中的高级类型4.1.class类4.2.class的构造函数4.3.class类的实例方法4.4.class继承extendsimplements 4.5.类的可见性修饰符公有的public受保护的protected私有的private 4.6.readonly只读属性4.7.类型兼容性4.8.对象之间的类型兼容性4.9.接口之间的兼容性4.10.函数之间的兼容性参数个数函数参数返回值返回值是原始类型返回值是对象类型 4.3.交叉类型4.4.交叉类型 和 接口继承 之间的比对4.5.*泛型创建泛型函数调用泛型函数简化函数的调用泛型约束指定更加具体的类型**添加约束***多个泛型变量情况 泛型接口数组是泛型接口泛型类泛型工具类PatialReadonlyPickRecord 4.6.索引签名类型4.7.映射类型4.8.映射类型(keyof)4.9.索引查询类型查询单个查询多个 5.**类型声明文件TS中的两种文件类型类型声明文件的使用说明 5.1.创建自己的类型声明文件项目内共享类型为已有的JS文件提供类型声明declare关键字 TypeScript入门 2.编译并运行TS代码 创建hello.ts文件 const info : string hello ts;console.log(info) 将TS文件编译为JS文件在终端中输入命令 tsc .\hello.ts 此时该目录下会生成一个同名的JS文件 执行JS代码在终端中输入命令 node hello.js 即可执行刚刚的js文件 需要注意的是TS编译生成的JS文件中代码中就没有类型的信息了。 2.1.简化运行ts步骤 简化方式 通过ts-node包可以直接在node中运行ts代码不用每次再使用ts进行编译 在使用node进行运行 npm i -g ts-node# 使用 就可以实现编译运行两步操作 # 注意 ts-node 并没有生成js文件他在内部偷偷帮你转换并且运行 ts-node hello.ts 3.TS中的常用类型 在TypeScriptTS中类型系统是其核心特性之一为JavaScript增添了静态类型检查的能力从而提高代码的可维护性和安全性。 也可以将TS中测常用基础类型细分为两类 JS已有类型 原始类型number/string/boolean/null/undefined/symbol对象类型object(包括 数组、对象、函数等对象) TS新增类型 联合类型、自定义类型、接口、元组、字面量类型、枚举、void、any等 以下是TypeScript中一些常用且重要的类型 基本类型 string用于文本字符串。number用于数值包括整数和浮点数。boolean布尔值只能是true或false。null 和 undefined表示空值或未定义的值TypeScript 中它们是所有类型的子类型。void表示没有任何返回值的函数。never表示永远不会出现的值的类型常用于抛出异常或无限循环的函数。 数组类型 使用Array元素类型或元素类型[]定义例如number[]表示一个数字数组。 元组Tuple 定义固定长度和类型的数组例如[string, number]表示一个数组其第一个元素为字符串第二个元素为数字。 对象类型Object 使用接口interface或类型别名type来描述对象结构如 interface Person {name: string;age: number; }枚举Enum 用于定义一组命名的常量如 1enum Color {Red, Green, Blue}任意类型any 表示可以是任何类型使用时需谨慎因为它绕过了类型检查。 联合类型Union Types 使用管道符号|分隔表示一个值可以是多种类型中的一种如string | number。 类型断言Type Assertion 用来告诉编译器某个值的类型形式为value as Type。 字面量类型Literal Types 直接使用具体的值作为类型如const answer: 42 42;。 索引签名Index Signatures 用于定义对象中动态属性的类型如{ [key: string]: any }。 类Class和接口 类用于创建对象的蓝图接口用于定义类或对象的形状。 泛型Generics 提供了编写可重用组件的方式这些组件可在多种数据类型上工作如ArrayT。 3.1.TS中的类型注解 示例代码 // 只需要在 变量后面 : 具体的类型 即可 let age : number 19代码中的 number 类型就是类型的注解作用就是为变量添加类型约束比如上面为age类型添加了 number类型的约束数值类型一旦约定了什么类型就只能给变量赋值什么类型否则就会报错 3.2.TS中的原始类型 原始类型number/string/boolean/null/undefined/symbol 这些类型完全按照JS中类型的名称来书写即可非常简单。 /* number/string/boolean/null/undefined/symbol */ let age : number 30 let username : string 张三 let isRunning : boolean trueconsole.log(年龄,age) console.log(姓名,username) console.log(是否在奔跑,isRunning)3.3.TS中的数组类型 对象类型object包括数组、对象、函数等对象。 对象类型在TS中更加细化每个具体的对象都有自己类型的语法 数组类型的写法 推荐使用 number[] 这种写法 let numbers : number[] [1,3,3,4,5,6,7,8,9,10] let strings : Arraystring [1,2,3,4,5,6,7,8,9,10]console.log(numbers) console.log(strings) 3.4.TS中的联合类型 当数组中既有number类型又有string类型这个数组的类型该如何书写的 如果数组中既有number类型 又有string类型这时候需要使用 | ts中的联合类型由两个或者多个类型组成类型表示可以是这些类型中的任意一种主要这里只是 | 一个竖线不是两个 两个 || 是逻辑表达式 let listInfo : (string | number | boolean)[] [1,2,3,4,true]// 打印当前集合数据 以及类型 listInfo.forEach(item{console.log(item \t\t typeof(item)) }) 3.5.类型别名 类型别名自定义类型为任意类型起别名 当一个类型复杂并且多次被使用时可以通过类型别名简化该类型的使用。 // 类型别名 type CustomArray (number | string | boolean)[]let user1 : CustomArray [张三,21,true]user1.forEach(item{console.log(item \t typeof(item)) }) 使用 type 关键字来创建类型的别名。类型别名可以是任意合法的变量名称。创建类型别名后直接使用该类型别名作为变量的类型注解即可。 3.6.函数类型 函数的类型实际上指的是函数的参数 和 函数的返回值 类型 为函数指定类型的两种方式 单独指定参数、返回值类型。同时执行参数、返回值类型。 3.6.1.单独执行参数、返回值类型 // 函数表达式形式 const add (num1: number, num2: number): number {return num1 num2; } const res add(1, 2) console.log(最终计算结果 res \t typeof (res) \t)3.6.2.同时指定参数返回值类型 ​ const addNum : (num1:number, num2:number) number (num1,num2){return num1 num2; } const res addNum(1,3)console.log(最终计算结果 res \t typeof (res) \t) 当函数作为表达式时可以通过 类似箭头函数形式的语法 来为函数添加类型 注意这种形式只适用于函数表达式 3.6.3.函数的void类型 如果函数没有返回值那么函数的返回值类型就为 void const getUserName (name: string): void {console.log(name) } getUserName(迪加)3.6.4.函数可选参数* 当使用函数实现某个功能时参数可以传也可以不传。这种情况下在给函数参数指定类型时就用到可选参数了。 比如数组中的 slice方法 可以使用 slice() 也可以使用 slice(1) 也可以使用 slice(1,3) const mySlice (start?: number, end?: number): void {console.log(起始索引 start \t 结束索引 end) }// 使用了可选参数那么我们自定义的 mySlice()中的参数 可以传 也可以不传了 mySlice() mySlice(1) mySlice(1, 3)可选参数在可传 可不传的参数后面添加问号 注意可选参数只能出现在参数列表的最后可选参数后面不能再出现参数 3.7.TS中的对象类型 JS中的对象是由属性和方法构成的而TS中对象的类型就是在描述对象的结构有什么属性 和 方法 对象类型的写法 // 单行形式 let person2: { name: string; age: number; show(): void; } {name: 张三,age: 19,show() {console.log(你好我是 this.name \t 我今年 this.age 岁了);} } // 多行形式 let person: {name: string,age: number,show(): void } {name: 张三,age: 19,show() {console.log(你好我是 this.name \t 我今年 this.age 岁了);} }person.show()直接使用{}来描述对象结构属性采用 属性名类型 的形式方法采用 方法名():返回值类型 的形式如果方法有参数就在方法名称后面的小括号中指定类型参数 例如show(name:string):void在一行代码中指定对象的多个属性类型时使用;(分号)来分隔 如果一行代码只能指定一个属性类型通过换行来分割多个属性类型可以去掉 ;(分号)方法的类型可以使用箭头函数的形式比如{show:()void} TS对象中的可选属性 对象的属性或者方法也是可选的此时就需要用到可选属性 比如我们在使用axios({ … })时如果发送GET请求mothod属性就可以省略 // 如果我们不传methods 那么默认的请求方式就是get // 可选属性的语法 与 函数的可选参数语法一直 使用 ? 来表示 const myAxios (config: { url: string, method?: string }): void {console.log(config); }myAxios({ url: http://localhost:9000/api/v1/test }) myAxios({ url: http://localhost:9000/api/v1/test, method: POST })3.8.接口 当一个对象类型被多次使用的时候一般会使用接口interface来描述对象的类型达到复用的目的 /*** 定义接口*/ interface IPerson {name: string,age: number,printInfo(): void }let personInfo: IPerson {name: 张三,age: 22,printInfo() {console.log(姓名 this.name 年龄 this.age);} }personInfo.printInfo()使用interface关键字来声明接口接口名称可以是任意合法的变量名称声明接口后直接使用接口名称作为变量的类型因为每一行只有一个类型属性因此属性后面没有 ;分号 接口 和 类型别名的对比 相同点都可以给对象指定类型不同点 接口只能为对象指定类型类型别名不仅可以为对象指定类型实际上可以为任意类型指定别名 /*** 定义接口*/ interface IPerson {name: string,age: number,printInfo(): void }/*** 定义类型 注意这里后面有一个 相当于把对象的结构赋值给TPerson*/ type TPerson {name: string,age: number,printInfo(): void }type NumStr number | string接口继承 如果两个接口之间有相同的属性或者方法 可以将公共的属性或者方法抽离出来通过继承来实现复用 比如 下面两个接口 都有 x 和 y 两个属性重复写两次虽然可以但是很繁琐。 interface Point2D {x: number,y: number }interface Point3D {x: number,y: number,z: number }更好的方式 interface Point2D {x: number,y: number }interface Point3D extends Point2D{z: number }使用了 extends(继承)关键字 实现了 Point3D接口继承 Point2D接口继承后Point3D就拥有了Point2D所有的属性和方法 let point_info:Point3D {x:1,y:2,z:3 }console.log(point_info);3.9.元组 在地图中经常使用经纬度坐标来标记位置信息 可以使用数组来记录坐标那么该数组的中只有两个元素并且这两个元素都是数值类型 let position: number[] [39.3232, 116.1232]使用number[]的缺点不够严谨因为该类型的数组中可以出现任意多个数字。 更好的方法可以使用元组Tuple 元组类型是另一种类型的数组它准确的直到了包含了多个元素以及特定索引位置的对应类型 let position: [number, number, boolean] [39.3232, 116.1232, true]元组类型可以确切的标记出有多少个元素以及每个元素的类型该示例中元素有3个元素前两个元素的类型是number,第三个元素的类型是boolean 3.10.类型推论 在TS中某些没有明确指出类型的地方TS的类型推断机制就会帮助提供类型。 发生类型推论的两种常见场景 声明变量并初始化时决定函数返回值时 // 声明变量时 let age 12// 决定函数返回类型时 const addNumer (num1: number, num2: number) {return num1 num2; }这两种情况下类型注解可以进行省略不写 推荐能省略的类型注解的地方就省略充分利用ts类型推论的能力偷懒 3.11.函数类型断言 在开发的过程中有的时候我们比TS更加能明确一个值的类型可以使用类型断言来指定更具体的类型 !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title /head bodya hrefwwww.baidu.com idlink跳转到百度网址/a /body /html scriptconst linked document.getElementById(link) /script注意getElementById方法返回值的类型时HTMLElement该类型只包含了所有标签的公共的属性或者方法不包含a标签特有的href等属性 因此这个类型不太具体无法操作href等a标签特有的属性 和 方法 解决方式这种情况下就需要使用类型断言指定更加具体的类型 as关键字 script typetext/typescript// 如果我们指定的HTMLElement 是无法获取的href等属性的const linked document.getElementById(link) as HTMLAnchorElement/script使用as关键字实现类型断言关键字as后面的类型是一个更加具体的类型HTMLAnchorElement是HTMLElement的子类型通过类型断言linked的类型变得更加具体这样就可以访问a标签中的特有的属性和方法了 第二种方式 这种方式不是很常用大家作为了解即可,在React中 这种语法格式和jsx冲突 所以用不了的 // 如果我们指定的HTMLElement 是无法获取的href等属性的const linked HTMLAnchorElementdocument.getElementById(link)console.log(a标签的值为,linked)console.dir($0) 可以打印当前第一个dom元素并且在列表的最后可以看到该元素的类型 3.12.字面量类型 思考下面代码两个变量类型分别是什么 let str1 Hello TSconst str2 Hello TS通过TS的类型推论机制可以得到答案 变量str1的类型为string变量str2的类型为Hello TS 解释 str1 是一个变量 let ,它的值可以是任意字符串所以类型为stringstr2 是一个常量 const , 它的值不能变化只能是’Hello TS’所以他的类型为Hello TS 注意 此处的 Hello TS 就是一个 字面量类型。也就是说某个特定的字符串也可以作为TS中的类型。除了字符串外任意的JS字面量比如对象数字等都可以作为类型使用 使用场景字面量类型配合联合类型一起使用用来表示一组明确的可选值列表 比如在贪吃蛇蛇的游戏中游戏的方向只能是 上、下、左、右的其中一个。 const changeDirection (direction: up | down | left | right) {console.log(输入的方向是, direction); }changeDirection(up)changeDirection(1)参数direction的值只能是 up/down/left/right的中的任意一个相对于string 类型使用字面量类型更加精确严谨。 3.13.枚举 枚举的功能类似于字面量类型联合类型的组合功能也可以表示一组明确的可选值。 **枚举定义一组命名常量。**它描述一个值该值可以是这些命名常量中的一个。 enum Direction { Up, Down, Left, Right } const changeDirection (direction: Direction) {console.log(输入的方向是, direction); } changeDirection(Direction.Up)使用enum关键字来定义枚举。约定枚举名称、枚举中的值以大写字母开头。枚举中的多个值通过逗号分隔。定义好枚举后直接使用枚举名称作为类型注解 注意形参中的direction的枚举类型为Direction,那么实参的值就应该是枚举Direction成员中的任意一个 访问枚举成员dirction.Up类似于JS中的对象直接通过 点(.)语法访问枚举的成员。 枚举成员的值以及数字枚举 当我们把枚举成员作为了函数的实参那么它的值是什么呢 当我们把将鼠标放到对应的枚举类型上时可以看到枚举成员Up的值是为0的。 注意其实枚举成员是有值的默认为从0开始的自增的数值。 我们把枚举成员的值为数字的枚举称为数字枚举 当前也可以给枚举成员中得到成员初始化值 enum Direction { Up 10, Down, Left, Right }字符串枚举 字符串枚举枚举的成员的值是字符串 enum DirectionStr { Up UP, Down DOWN, Left LEFT, Right RIGHT } console.log(DirectionStr.Left);注意字符串枚举没有自增长行为因此字符串枚举的每个成员都必须有初始值。 3.14.any类型 原则上不推荐使用any 这个会让TypeScript变为 AnyScript 失去TS类型保护的优势 因当值为any类型时可以对该值进行任意操作并且不会有代码提示 let obj: any { x: 0 }obj.bar 100obj()const n: number obj上面的代码操作不会有任何类型的错误提示即使可能存在报错 应该尽可能避免使用any除非临时使用any来避免 书写很长 很复杂的类型 其他隐式具有any类型的情况 声明变量不提供类型也不提供默认值函数参数不加类型 注意这两种情况下都应该去提供类型防止出现运行时错误 3.15.typeof 在JavaScript中提供了typeof操作符用来获取数据的类型 实际上TS也提供了 typeof操作符可以在类型上下文中引用变量 或 属性的类型。 使用场景根据已有变量的值获取该值的类型来简化书写 // 使用typeof来简化类型的书写let p { x: 1, y: 2 } const printPointInfo (point: { x: number, y: number }) {console.log(x:, point.x);console.log(y:, point.y); } printPointInfo(p) console.log(----------------------------------------);// 因为 ts 可以根据值 去推断属性的类型 那么可以简化书写 const printPointInfoNew (point: typeof p) {console.log(new-x:, point.x);console.log(new-y:, point.y); } printPointInfoNew(p)使用 typeof 操作符获取变量p的类型结果 和第一种相同typeof出现在类型注解的位置参数名称的冒号后面所处的环境就在类型的上下文typeof只能用来查询变量或者属性的类型无法查询其他形式的类型比如函数的调用类型 4.TS中的高级类型 TS中的高级类型有很多重点学习以下高级类型 class类类型兼容性交叉类型泛型 和 keyof索引签名类型 和 索引查询类型映射类型 4.1.class类 TypeScript全面支持ES2015中引入的 class关键字并且为其添加了类型注解 和 其他语法 如可见性修饰符等 class的基本使用 class Person {/*** 姓名*/name: string }const person new Person()console.log(person);根据TS中的类型推断可以直到Person类的实例对象 person的类型是 PersonTS中的class不仅提供class的语法功能也可以作为一种类型的存在 实例属性的初始化 /*** 人*/ class Person {/*** 姓名*/name: string;/** * 性别*/gender 男生 }声明成员 age类型为number(没有初始值)声明成员 gender并设置初始值此时可以省略类型注解TS类型推论为string类型 4.2.class的构造函数 class Person {name: stringgender: stringconstructor(name: string, gender: string) {this.name namethis.gender gender} }const person new Person(张三,女生) console.log(person.name) console.log(person.gender) console.log(person);成员初始化比如age:number后才可以通过 this.age访问实例成员。需要为构造函数指定类型注解否则会被隐式推断为any构造函数不需要返回值类型 4.3.class类的实例方法 class Point{// 这里如果给定默认值 那么就不用写构造方法了x : numbery : numberconstructor(x:number,y:number){this.x xthis.y y}/*** 计算方法* param num 计算的比例数*/scale(num: number):void{this.x * numthis.y * numconsole.log(this.x);console.log(this.y);} } const p new Point(1,2) p.scale(100)方法的类型注解参数和返回值与函数的用法相同 4.4.class继承 类的继承有两种方式 通过 extends(继承父类)通过implements(实现接口) JS中只有 extends但是TS提供了implements extends /*** 动物通用父类*/ class Animal {move() {console.log(Moving along!)} }/*** 小狗类*/ class Dog extends Animal{bark() {console.log(汪汪)} }const dog new Dog()// 调用父类的移动方法 dog.move() dog.bark() 通过extends关键字实现继承子类Dog继承父类Animal则Dog的实例对象dog就同时具有了父类的Animal 和 子类 Dog的所有的属性和方法 implements interface CommonPrint {/*** 通用输出方法* param name 输出的信息*/print(name: string): void }/*** 手机实现类-输出手机信息*/ class PhonePrint implements CommonPrint {print(name: string) {console.log(当前手机的型号为, name)} }const phone new PhonePrint() phone.print(Iphone 16 Pro Max)通过implements关键字让class实现接口PhonePrint类是实现CommonPrint意味着PhonePrint类中必须提供CommonPrint接口中指定的所有方法和属性 4.5.类的可见性修饰符 类成员可见性可以使用TS来控制class的方法 或 属性 对于calss外的代码是否可见 可见性修饰符包括 public(公有的) public表示公有的公开的公有成员可以被任何地方访问默认可见性一般不写就是公有的 protected(受保护的)private(私有的)、 公有的public class PhonePrint implements CommonPrint {public print(name: string) {console.log(当前手机的型号为, name)} }受保护的protected protected表示受保护的仅对其声明所在类和子类中非实例对象可见对实例对象不可见不可见不可见 class Father{protected money:10000000000 }class Son extends Father{print(){console.log(Father Money:,this.money)} }const son new Son()son.print()// 子类实例对象时不可见的 但是在对应的子类中 是可以访问得到 son.moeny私有的private 私有属性或方法只能在当前类中可见对其子类和实例对象也是不可见的 class Father{private money:10000000000 }class Son extends Father{print(){console.log(Father Money:,this.money)} }4.6.readonly只读属性 除了可见性修饰符之外还有一个比较常见的修饰符号就是 readonly(只读修饰符) readonly表示只读用来防止在构造函数之外对属性进行赋值 class Person {readonly age: numberconstructor(age: number) {this.age age} }const person new Person(12) person.age 11// 接口 interface IPerson{readonly name : string }let obj:IPerson {name : Jack }obj.name rose// {} 表示类型 let obj: { readonly name: string } {name: Jack }obj.name rose使用readonly关键字修饰的属性是只读的注意readonly只能修饰属性不能修饰方法接口或者{}表示的类型也可以使用readonly 4.7.类型兼容性 两种类型系统 Structural Type System (结构化类型系统)Nominal Type System标明类型系统 TS采用的是 结构化类型系统也叫做 duck typing(鸭子类型)类型检查关注的是值所具有的形状。也就说在结构类型系统中如果两个对象具有相同的形状则认为他们属于同一类型。 class NewPoint {x: numbery: number }class NewPoint2d {x: numbery: number }const p1: NewPoint new NewPoint2d()// 为变量赋值 p1.x 12 p1.y 33// 打印当前实例 console.log(p1); NewPoint 和 NewPoint2d是两个不同名称的类变量p1的类型被显式标注为NewPoint类型但是他的值确实Point2D的实例并没有类型的错误因为TS是结构化类型系统只检查NewPoint 和 NewPoint2d的结构是否相同相同都具有 x 和 y 两个属性属性类型相同但是 在Nominal Type System中比如C#,Java中他们就是不同的类无法兼容 4.8.对象之间的类型兼容性 在结构系统中如果两个对象具有相同的形状则认为他们属于同一种类型这种说法不准确 更准确的说对于对象类型来说y的成员至少与x相同则x兼容y 成员多的可以赋值给少的 class NewPoint {x: numbery: numberconstructor(x:number,y:number){this.x xthis.y y} }class NewPoint3d {x: numbery: numberz: numberconstructor(x:number,y:number,z:number){this.x xthis.y ythis.z z} }const p1: NewPoint new NewPoint3d(1,3,3)// 打印当前实例 console.log(p1)NewPoint3d 的成员至少 和NewPoint相同则 NewPoint 兼容 NewPoint3d成员多的Point3D可以赋值给成员少的NewPoint 4.9.接口之间的兼容性 除了class之外TS的其他类型也存在相互兼容的情况包括 接口兼容性函数兼容性 接口之间的兼容性类似于class 并且class和interface之间也可以兼容 interface NewPoint {x: number}interface NewPoint2d {x: numbery: number}interface NewPoint3d {x: numbery: numberz: number }// 类 和 接口之间也是相互兼容的 class NewPoint4d {x: numbery: numberz: numberconstructor(x:number,y:number,z:number){this.x xthis.y ythis.z z} }let p99 : NewPoint3d let p98 : NewPoint2d // 声明p97 类型为 NewPoint let p97 : NewPoint p97 new NewPoint4d(1,2,3)console.log(p97); 4.10.函数之间的兼容性 函数之间的兼容性比较复杂需要考虑 参数的个数参数的类型返回值类型 参数个数 参数个数参数多的个数可以兼容参数少的个数参数少的可以赋值给参数多的 // 函数参数的返回类型 let function1 (a: number): void { }let function2 (a: number, b: number): void { }// 参数少的function1 可以赋值给参数多的function2 function2 function1// 参数多的不能赋值给参数少的 function1 function2 // 函数参数的返回类型 type F1 (a: number) voidtype F2 (a: number, b: number) void// 这里如果不给声明变量赋值初始值会报错 let f1: F1 (a: number) { } let f2: F2 (a: number, b: number) { } f2 f1console.log(f2);let arr [a, b, c] // 上面数组中示例的类型为(method) Arraystring.forEach(callbackfn: (value: string, index: number, array: string[]) void, thisArg ?: any): void arr.forEach(() { }) arr.forEach((item) {console.log(item); }) arr.forEach((item, index) {console.log(item, -, index); })arr.forEach((item, index, arr) {console.log(item, -, index, -, arr); }) 参数少的可以赋值给参数多的所以 function1 和 赋值给 function2数组forEach方法的第一个参数是回调函数类型为 (value: string, index: number, array: string[]) void再JS中省略用不到的函数参数实际上是非常常见的这种使用方式促成了TS中函数类型之间的兼容性并且因为回调函数是有类型的所以TS会自动推导出 item index array的类型 -** 函数参数 函数参数相同位置的参数类型要相同原始类型或兼容对象类型 type F1 (a: number) stringtype F2 (a: number, b: number) stringlet f1: F1 (a: number) // 参数少的兼容参数多的但是参数多的不能兼容参数少的 let f2: F2 f1console.log(f2的类型是, f2);函数类型F2 兼容 函数类型F1 因为F2 和 F1的第一个参数相同 返回值 返回值比较简单我们只关心返回值的类型即可 返回值是原始类型 // 下面这个是错误的一个演示type F1 (a: number) numbertype F2 (a: number, b: number) stringlet f1: F1 (a: number) 0 let f2: F2 f1// 正确写法 type F1 (a: number) stringtype F2 (a: number, b: number) stringlet f1: F1 (a: number) let f2: F2 f1 返回值是对象类型 type F1 () { name: string }type F2 () { name: string, age: number }let f2: F2 () { return { name: 张三, age: 123 } } let f1: F1 f1 f2console.log(f1,f1); 注意 如果返回值类型是原始类型此时两个类型要相同 比如 f1 和 f2 返回值类型都是string类型如果返回值类型是对象类型此时成员多的可以赋值给成员少的 比如 下面的 f2 和 f1 f2的返回值类型 比 f1的返回值类型 多了个age 4.3.交叉类型 **交叉类型**功能类似于接口继承extends,用来组合多个类型为一个类型常用于对象 比如 interface Person {name: string } interface Concat {phone: string }type PersonAndConcat Person Concatlet obj: PersonAndConcat {name: 迪迦,phone: 15256412345 } console.log(obj:, obj); 使用交叉类型后新的类型PersonAndConcat就同时 具备了 Person 和 Concat的所有属性类型 相当于 type PersonAndConcat { name: string, phone: string }4.4.交叉类型 和 接口继承 之间的比对 交叉类型和 继承extends的对比 相同点都可以实现对象类型的组合不同点两种方式都可以实现类型组合对于同名属性之间处理类型冲突的方式不同 // 继承 interface A {print(value: number): string } interface B extends A {print(value: string): string }// 交叉 interface C {print(value: number): string } interface D {print(value: string): string } type E A B// 其实 A B 可以理解为 print(value : string | number): string上面代码接口继承的时候会报错类型不兼容但是交叉类型没有报错 4.5.*泛型 泛型是可以再保证安全的前提下让函数等多种类型一起工作从而实现复用常用于函数、接口、class中。 需求创建一个id函数传入什么类型数据就返回该数据本身参数和返回值类型一致 // 上面函数 只能接受字符串类型的如果其他的类型的就不兼容了 // 可以使用any来处理但是使用any后就失去了TS类型保护 const getUserName (username: string): string { return username }const getUserName (username: any): any { return username }这个时候就可以使用泛型来处理泛型在保证类型安全不丢失类型信息的同时可以让函数等与多种不同类型一起工作灵活复用。 创建泛型函数 // 第一种写法 const getUserName T(username: T): T { return username }// 第二种写法 function getUserInfoT(value: T): T {return value }type UserInfo {username: string }console.log(getUserNameUserInfo({ username: 张三 })); 语法在函数名称的后面添加(尖括号)尖括号中添加类型变量 例如此处的 T类型变量 T 是一种特殊类型的变量他处理类型而不是值该类型变量相当于一个类型容器能够捕获到用户提供的类型(具体何种类型由用户调用该函数时指定)因为T是类型因此可以将其作为函数的参数和返回值类型表示参数 和返回值具有相同的类型类型变量Type,可以是任意合法的变量名称 调用泛型函数 getUserNameUserInfo({ username: 张三 })语法 语法在函数名称后面添加 (尖括号)尖括号中指定具体的类型比如 此处的UserInfo当传入UserInfo类型后这个类型就会被函数声明时指定的类型变量 Type捕获到次数Type的类型 就是 UserInfo所以id参数和返回值类型也是UserInfo 这样通过泛型就做到了让 getUserName函数 和 多种不同的类型在一起工作从而实现了复用的同时保证了类型的安全 简化函数的调用 const getUserName T(username: T): T { return username }const getId T(id: T): T { return id }let id getIdstring(迪迦)// 在调用函数的时候 可以省略 类型来简化泛型函数的调用 let id2 getId(泰罗)在调用泛型函数时可以省略类型来简化泛型函数的调用此时的TS内部会采用一种叫做 类型参数推断的机制来根据传入的实参自动推断出类型变量Type的类型 泛型约束 默认情况下泛型函数的类型变量Type可以代表多个类型这就导致无法访问任何属性。比如 getId(‘a’)调用函数时获取参数的长度 const getId T(value: T): T {console.log(value.length);return value; }function getIdNewT(value: T): T {console.log(value.length);return value; }T可以代表任意类型无法保证一定存在length属性比如number类型就没有length此时需要为泛型 添加约束来收缩类型缩窄类型取值范围 添加泛型约束收缩类型主要有以下两种方式 指定更加具体的类型添加约束 指定更加具体的类型 比如将类型 修改为T[] (T类型的数组)因为只要时数组就一定存在length属性了因此就可以访问了 const getId T(value: T[]): T[] {console.log(value.length);return value; }function getIdNewT(value: T[]): T[] {console.log(value.length);return value; }console.log(getId([张三,1,2])); console.log(getId([李四,3,4,5]));添加约束 interface ILength {length: number } const getId T extends ILength(value: T): T {console.log(value.length);return value; }function getIdNewT extends ILength(value: T): T {console.log(value.length);return value; }console.log(getId([迪加, 1, 2])); console.log(getId([赛文, 3, 4, 5]));创建描述约束的接口 ILength该接口中要求提供length属性通过extends关键字使用该接口为泛型类型变量添加约束该约束表示传入的类型必须具有length属性 *多个泛型变量情况 泛型的类型变量可以有多个并且类型变量之间还可以约束(比如第二个类型变量受第一个类型变量约束) const getPorp T, K extends keyof T(obj: T, key: K) {console.log(Object:, obj);console.log(Key:, key);return obj[key] }console.log(getPorp({name: 迪加奥特曼,age: 999999999,addrees: null }, name)); 添加了第二个类型变量 K,两个类型变量之间使用,分隔keyof 关键字 接受一个对象类型生成其键名称可能是字符串或者数字的联合类型上面案例中 keyof T 实际上获取的 是 对象的所有键的联合类型也就是name| age | address类型变量 K 受 T 约束可以理解为K 只能是 T 所有键中的任意一个或者只能访问对象中存在的属性 泛型接口 泛型接口接口也可以配合泛型来使用增加其灵活性增强其复用性 interface BookT {getBookName: (value: T) T }let book: Bookstring {getBookName(value) {return value;}, }console.log(book.getBookName(Java开发入门));在接口名称后面添加类型变量那么这个接口就变成了泛型接口。接口的类型变量对接口中所有其他成员可见也就是接口中所有成员都可以使用类型变量使用泛型接口时需要显式指定具体的类型比如 Book 此时id方法的参数 和返回值类型都 string 数组是泛型接口 // 泛型数组 // 实际上JS中的数组在TS中就是一个泛型接口const strs [a, b, c]const nums [1, 2, 3, 4, 5]当我们在使用数组时TS会根据数组的不同类型来自动将类型变量设置为相应的类型。 泛型类 class GenericNumberNumType {defaultValue: NumTypeadd: (x: NumType, y: NumType) string (x, y) {console.log(x);console.log(y);return success;}// 可以省略尖括号 当类中提供了constructor 并且提供了属性 那么就不需要在 显式的声明类型了constructor(value: NumType) {this.defaultValue value} }const myNum new GenericNumber(100)// 推荐明确指定泛型类型 const myNum1 new GenericNumbernumber(100) myNum1.defaultValue 10 myNum1.add(1, 2)console.log(myNum1); 类似于泛型接口在class名称后面添加**类型变量**这个类就成了泛型类 此处的add方法采用的是箭头函数形式的书写方式 const myNum1 new GenericNumbernumber(100)类似于泛型接口在创建class实例时在类名后面通过**类型**来指定明确类型 泛型工具类 TS中内置一些常用的工具类来简化一些TS中常见的操作 它们都是基于泛型实现的泛型适用于类型更加通用并且时内置的可以直接在代码中进行使用。 PatialReadonlyPickT,KRecordK,T Patial 用来 创建一个类型将 泛型T 的所有属性变成可选的。 // 泛型工具类interface Props {id: string,age: number,children: number[] }// 用来 创建一个类型将 泛型T 的所有属性变成可选的。 type PartialProps PartialProps构造出来的 PartialProps 和 Props 结构相同但是所有属性都变为可选了 Readonly 用来构造一个类型将 泛型T的所有属性设置为 readonly(只读) interface Props {id: string,age: number,children: number[] }type ReadonlyProps ReadonlyPropslet props: ReadonlyProps { id: 1, age: 12, children: [1, 2, 3] }props.children 14 Pick PickT,K 从T中选择一组属性来构造新的类型 interface Props {id: string,age: number,children: number[] }type PickProps PickProps, id | agelet pickProps: PickProps { id: 1212, age: 12 }console.log(pickProps); Pick工具类中两个类型 1表示选择谁的属性 2表示选择哪几个属性第二个参数如果只选择一个属性那么写一个参数就行了多个 就需要使用 | 进行拼接第二个参数传入的参数只能是第一个参数中存在的属性 Record 用来构造一个对象类型属性键 为K 属性类型为 T type RecordObj Recorda | b | c, string[]let obj: RecordObj {a: [1],b: [2],c: [3] } console.log(obj);Record工具类型有两个类型变量 表示对象有哪些属性表示对象属性的类型 构建的新对象类型RecordObj表示这个对象的三个属性分别为 a,b,c 属性值的类型都是 string[] 4.6.索引签名类型 在大多数情况下我们都可以是在使用对象前确定对象的结构并为对象添加准确的类型。 当无法确定对象中有哪些属性时此时就用到索引签名类型了 interface AnyObject {[K: string]: number }let obj: AnyObject {a: 1,b: 2 }// 可以指定对应其他类型 interface AnyObject {[K: number]: number }let obj: AnyObject {1: 1,2: 2 }使用[K: string]来约束接口中允许出现的属性名称。表示只要是string类型的属性名称都可以出现在对象中。这样对象中就可以 出现任意多个属性比如 abK 只是一个占位符可以替换成任意合法的变量名称Js中对象{}的建都是string类型 JS数组中的 也用到索引签名 4.7.映射类型 映射类型基于旧类型创建新的类型减少重复提升开发效率 // 这里相当于定义了键 type PrposKeys x | y | ztype TypeDefault { x: number, y: number, z: number } type Type { [Key in PrposKeys]: number }let obj: Type {x: 1232,y: 213,z: 12132 }console.log(obj);映射类型是基于索引签名类型的所以该语法类似于索引签名类型也使用了[]Key in PropKeys 表示Key 可以是PrposKeys类型中的任意一个类似于forin (let k in obj)使用映射类型创建的对象类型 Type 和 TypeDefault 完全相同注意映射类型只能在类型别名中使用不能在接口中使用 4.8.映射类型(keyof) 映射类型处理根据联合类型创建新类型还可以根据对象类型来创建 type PrposKeys { x: number, y: number, z: number, note: string }type PropsKeys2 { [Key in keyof PrposKeys]: number | string }let obj: PropsKeys2 {x: 1232,y: 213,z: 12132,note: 测试数据 }console.log(obj);首先先执行 keyof Props获取到对象类型的Props中所有建的联合类型x: number, y: number, z: number, note: string 然后 Key in 就表示 Key 可以是Props中所有的键名称中的任意一个 4.9.索引查询类型 查询单个 刚刚使用的 T[P]语法在TS中叫做索引查询类型作用就是用来查询属性的类型 type Props { name: string, age: number }type TypeA Props[age]注意[]中的属性必循存在于被查询的类型中否则就会报错 查询多个 type Props { name: string, age: number }// type TypeA Props[age | name] type TypeA Props[keyof Props]使用keyof操作符获取Props中所有键对应的类型结果为string | number 5.**类型声明文件 在项目开发中几乎所有的JS应用都会引入许多第三方库来完成任务需求这些第三方库不管是不是TS编写的最终都会变成JS代码才能给开发者使用我们直到TS提供了类型才有了代码提示和类型保护等机制。 在项目开发使用第三方库的时候你会发现他们几乎都有相应的TS类型这些类型怎么来的呢 类型声明文件 类型声明文件用来为已存在的JS库提供类型信息 这样在TS项目中使用这些库时就会像TS一样有代码提示、类型保护等机制了。 TS的两种文件类型类型声明文件的使用说明 TS中的两种文件类型 .ts文件 既可以包含类型信息又可以包含执行代码可以被编译成.js文件然后执行代码用途编写程序代码的地方 .d.ts文件 只包含类型信息的类型声明文件不会生成.js文件仅用于提供类型信息用途为js提供类型信息 总结.ts代码实现文件 .d.ts类型声明文件 类型声明文件的使用说明 在使用TS开发项目时类型声明文件的使用包括以下两种方式 使用已有的类型声明文件创建自己的类型声明文件 先学会怎么用别人得到再去写自己的 内置类型声明文件 TS为JS运行时可用的所有标准化内置了API都提供了声明文件比如我们在使用数组的时候数组的所有方法都会有相应的代码提示以及类型信息 实际上这些都是TS提供的内置类型声明文件可以通过Ctrl 鼠标左键 来查看内置类型声明文件 第三方库的类型声明文件 目前几乎所有常用的第三方库都有相应的类型声明文件 第三方库的类型声明文件主要有两种形式 库自带类型的声明文件有DefinitelyTyped提供 库自带的类型声明文件例如axios 这种情况下正常导入该库TS就会自动加载库自己的类型声明文件用来提供该库的类型声明。 由DefinitelyTyped提供 DefinitelyTyped是一个github仓库用来提供高质量的TypeScript类型声明 可以通过npm来下载该仓库提供的TS类型声明包这些包的名称格式为 types/* 比如下载 types/react 可以尝试使用 npm i --save-dev types/react(库的一些名称)安装后TS会自动加载该类声明包以提供该库的类型声明。 5.1.创建自己的类型声明文件 项目内共享类型 项目内共享类型如果多个 .ts文件中都用到同一个类型此时可以创建 .d.ts 文件提供该类型实现类型共享。 操作步骤 创建 user.d.ts 类型声明文件 // user.d.ts export type UserInfo {username: string,password: string } 创建需要共享的类型并使用export导出TS中中的类型也可以使用 import/export 实现模块化功能 在需要使用共享类型的 .ts 文件中通过import 导入即可.d.ts后缀导入时直接忽略即可 import { UserInfo } from ../types/user;let user: UserInfo {username:137230256,password:123456111 }console.log(user:[,user,]); 为已有的JS文件提供类型声明 什么时候需要为已有JS文件提供类型声明呢 在将JS项目迁移到 TS项目的时候为了让已有的 .js 文件有类型声明成为库作者创建库给其他人使用 注意类型声明文件的编写 与 模块化的方式相关不同的模块化方式有不同的写法。 演示基于最新的 ESModule(import/export)来为已有的.js文件创建类型声明文件 开发环境准备使用webpack搭建通过 ts-loader处理 .ts 文件 说明TS文件中也可也使用 .js 文件到导入 .js 文件时TS会自动加载 和 .js同名的 .d.ts文件以提供类型声明 declare关键字 用于类型声明为其他地方比如.js 文件已经存在的变量 声明类型而不时创建一个新的变量 对于 type 、 interface 等这些明确就是 TS类型的只能在TS中使用的可以省略 declare关键字对于 let funcation 等具有双重含义的在JS 和 TS 中都可以使用应该使用 declare关键字明确指定此处用于类型声明 1.创建JS文件 user.js export const getUserInfo (params){console.log(获取用户信息成功);console.log(params:,params); }2.创建 .d.ts文件 user.d.ts // 为方法的请求参数添加类型 declare type UserInfo {username: string,password: string }// 为js文件 的方法添加类型 declare function getUserInfo(params:UserInfo):void// 导出JS文件 export { getUserInfo } // 或者 module.exports { getUserInfo }; 3.测试 import { getUserInfo, UserInfoParams } from ./user;// 调用获取用户信息方法 let params: UserInfoParams {username: 1232,password: 2132434 }console.log(params);console.log(------------------------------------);getUserInfo(params) 如果无法使用 export 导出 js方法 那么可以换一种思路 package.json {compilerOptions: {module: commonjs} } user.js function getUserInfo(params) {console.log(获取用户信息成功);console.log(params:, params); }module.exports { getUserInfo };
http://www.zqtcl.cn/news/291999/

相关文章:

  • 网站怎么推广软文政务网站建设存在问题
  • 公司官方网站建设需要多少钱wordpress单页面制作
  • 社群网站建设网站推广的方式有哪几种
  • 培训机构活动策划网站wordpress 改端口
  • 北京网站制作与营销培训用asp做网站视频
  • 江苏丹阳建设公司网站做网站中的剪辑图片
  • 纯静态网站怎样广州工程造价信息网
  • 为什么网页不能打开建设银行网站企业网站开发综合实训
  • 企业网站制作 深圳网站建站行业公司主页建设
  • 外汇直播网站建设开发做网站空间商需要办什么手续
  • 源码哥网站的模板皮肤病在线咨询医生免费咨询
  • 温岭市市住房和城乡建设规划局网站附近的电脑培训班在哪里
  • 网站备案百度站长提交减肥网站源码
  • 网站添加文章机械代加工厂家
  • 学做各种糕点的网站cn网站建设多少钱
  • 首页网站关键词优化教程如何查询网站点击率
  • 文章类型的网站模版北京朝阳区房价2023年最新房价
  • wap网站发布注销主体和注销网站
  • 微信小程序 做网站满足客户的分销管理系统
  • 高佣联盟做成网站怎么做wordpress 更新版本
  • 杭州营销网站建设公司成都网站排名优化报价
  • 网站建设设计哪家好太原新建火车站
  • 医疗网站建设信息cps推广平台有哪些
  • rp怎么做网站备案 添加网站
  • 汕尾手机网站设计淘宝客做网站怎么做
  • 营口公司网站建设网站百度seo关键词优化
  • 网站开发命名规范汉中网站制作
  • 嘉定网站建设公司泗水做网站ys178
  • 邯郸网站设计招聘网齐家网和土巴兔装修哪家好
  • 京东网站推广方式jquery网页设计成品