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

网站建设互联网加大兴专业网站建设公司

网站建设互联网加,大兴专业网站建设公司,wordpress add_action,精准大数据获客系统文章目录 TypeScript 学习笔记概述TypeScript 开发环境搭建 类型注解类型推断 数据类型JS的7个原始类型Array数组object、Object 和 {}可选属性 ? 和 可选链运算符?. function函数TS类型: any类型 | unknow类型TS类型: void类型TS类型#xff1a;never类型 #xff08;几乎… 文章目录 TypeScript 学习笔记概述TypeScript 开发环境搭建 类型注解类型推断 数据类型JS的7个原始类型Array数组object、Object 和 {}可选属性 ? 和 可选链运算符?. function函数TS类型: any类型 | unknow类型TS类型: void类型TS类型never类型 几乎不用TS类型Tuple(元组)语法细节1.联合类型 | 和交叉类型 2.type和interface接口作为类型声明3.类型断言 as 和非空类型断言4.字面量类型和类型缩小5.函数的类型和函数签名函数表达式函数调用签名:支持声明属性构造签名(理解) 6.函数的重载和this类型函数的重载(通用库和工具中使用较多)this类型(很少使用)this相关的内置工具(了解) 7.函数的参数可选参数默认参数剩余参数 TypeScript 类的使用类的特性抽象类abstract TypeScript对象类型索引签名函数签名 TypeScript接口类实现接口 implements抽象类和接口的区别特殊:严格字面量赋值检测 TypeScript枚举类型泛型泛型语法的基本使用泛型约束和类型条件keyof 和 in TypeScript映射类型(开发中很少用用于封装组件)映射类型修饰符 TypeScript 学习笔记 概述 JavaScript的变量类型相当于是动态类型可以跟随着赋值的改变而类型改变函数的参数也没有设定类型所以在定位错误以及安全性上不太够。 说明 1.TS不能被JS解析器直接执行需要编译成JS执行 2.即使TS编译出错也可以编译成JS 1.TypeScript是什么 TypeScript 是类型安全的JavaScript(拥有类型的JavaScript超集)JavaScript是弱类型, 很多错误只有在运行时才会被发现而TypeScript提供了一套静态检测机制, 在编译时就发现错误 2.TypeScript的好处是什么 1.支持强类型 2.类型注解通过类型注解来增加编译时静态类型检查 3.增加了特性:泛型、接口、抽象类等 TypeScript 开发环境搭建 安装TS解析器 :解析器使用nodejs写的 — 先安装nodejs我node已经安装好啦直接安装TypeScript 1.使用npm全局安装TypeScript npm i -g typescript2.检查是否安装成功 tsc --version3.创建一个ts文件:后缀以ts结尾 使用tsc对ts文件进行编译进入到该文件的命令行,使用tsc 文件名进行编译 tsc test.tsTS运行效果查看 1.通过tsc编译TS代码到JS代码 2.在浏览器环境或者node环境下运行JS代码 简化版本 通过webpack 配置本地的TS编译环境和开启一个本地服务可以直接运行在浏览器上(ts-loader)通过ts-node库为TS的运行提供执行环境 # 安装ts-node npm install ts-node -g # 按照ts-node依赖包tslib types/node npm install tslib types/node - g # node上运行js node xxx.js # node上运行ts ts-node xxx.ts类型注解 类型注解:主动告诉ts是什么类型 语法:变量名:数据类型 说明 1.冒号后面的数据类型被称为类型注解★ 2.声明了类型后TS就会进行类型检测 类型推断 类型推断声明一个变量时如果有直接赋值会根据赋值的类型推导出标变量的类型注解。 说明 1.声明变量如果不指定类型也不赋值则TS解析器会自动判断变量的类型为any 2.从右到左推断 3.let进行类型推导推导出来是通用类型 const类型推导推导出来是字面量类型 const height 1.88 //1.88为heigth的类型1.88是字面量类型 const height:1.88 //等价于数据类型 JS数据类型: 7个原始类型 (string,number,boolean,undefined,null,bigint,symbol) Array ObjectTS新增类型: any unknow void never 总结 1.默认情况下 null 和 undefined 是所有类型的子类型这两种类型可以赋值给任意类型的变量 4.never类型是任何类型的子类型也可以赋值给任何类型的变量 2. unknown 是 顶级类型任何类型的值(never除外)都可以赋值给该类型的变量 3. any 是顶级类型任何类型的值(never除外)都可以赋值给该类型的变量也是所有类型的子类型any相当于关闭类型检测 JS的7个原始类型 let str: string jimmy; let num: number 24; let bool: boolean false; let u: undefined undefined; let n: null null; let big: bigint 100n; let sym: symbol Symbol(me); 说明 1.默认情况下 null 和 undefined 是所有类型的子类型。 可以把 null 和 undefined 赋值给其他类型。 如果你在tsconfig.json指定了strictNullChecks:true null 和 undefined 只能赋值给 void 和它们各自的类型。 2.String是JavaScript中字符串包装类 Array数组 //明确指定数组的类型注解写法1 let arr:string[] [1,2]; //明确指定数组的类型注解写法2 泛型写法 let arr2:Arraystring [1,2]object、Object 和 {} 语法:{属性名:属性值,属性名:属性值....} 说明 1.属性个数名字必须一模一样不能多不能少 2.分割符分号和逗号可以换行可以省略分号因为JS中换行会自动添加分号最好使用逗号。 3.object、Object 和 {} Object 代表所有拥有 toString、hasOwnProperty 方法的类型所有原始类型、非原始类型都可以赋给 Object。在严格模式下null 和 undefined 类型也不能赋给 Object。{}等价于Objectobject 则表示非原始类型 let info: object {name: why,age: 18} info [1,2,3]; //非原始类型 console.log(info); info 123; //报错4.类型不注解默认为any 以下写法在实际开发中并不会使用因为object并不清楚里面的属性是什么类型获取到对象里的属性会报错。 //不使用 let info: object {name: why,age: 18 } console.log(info[age]) //报错/* 写法1 let info: { name:string age:number } 写法2 let info: {name:string;age:number} 写法3 let info: {name:string,age:number} */ let info: { name:string age:number } {name: why,age: 18 }可选属性 ? 和 可选链运算符?. 可选属性? 如果某一属性不确定可以使用?标识该属性可选 语法:{属性名:属性值,属性名?:属性值} 可选链运算符?. ?.用来判断左侧的表达式是否是 null | undefined如果是则会停止表达式运行可以减少我们大量的运算。 a null || a void 0 ? void 0 : a.b;function getData(data: any){let name data?.row?.name //data data.row ? data.row.name:undefined } //普通写法 function getData(data: any){let name;if (data data.row) {name data.row.name} }比如我们写出a?.b时 理解1:a ? a.b :undefined 理解2:如果a为null或者undefined则后面的表达式等于没有如果存在则获取a.b 访问属性的时候可以用可选链但是赋值时不可以使用比如: xxx?.xxxxxx function函数 function add(x: number, y: number): void {x y; }1.匿名函数 - 大多数时候不需要类型注解 当一个函数出现在TS可以确定该函数会被如何调用的地方时,该函数的参数会自动指定类型,最好不要加类型注解 const names [abc, cba, nba] // 根据上下文环境推导出来的这个时候可以不添加类型注解 // 上下文中的函数可以不添加类型注解 names.forEach(function (item,index,arr) {console.log(item,index,arr) })这是因为TypeScript会根据forEach函数的类型以及数组的类型推断出item的类型 这个过程称之为上下文类型contextual typing因为函数执行的上下文可以帮助确定参数和返回值的类型 TS类型: any类型 | unknow类型 1.在 TypeScript 中任何类型都可以被归为 any 类型因此any 类型也是类型系统的顶级类型。 2.变量如果在声明的时候未指定其类型会被识别为任意值类型。 3.unknown与any一样所有类型都可以分配给unknown 都表示不清楚是类型。 unknown 是 top type (任何类型都可以赋值给unknow类型) , 而 any 既是 top type, 又是 bottom type (任何类型都可赋值给any类型的变量any类型可以赋值给任何类型) 。 区别赋值描述anyany上访问任何属性都是允许的,也允许调用任何方法any 类型可以赋值给任意类型any相当于关闭类型检验unknow默认情况下unknow类型上不能访问属性和调用方法(执行任何操作?),必须进行类型校验(缩小)才可以执行对应操作unknow 类型只能赋值给 any 和 unknow 类型unknow是更加安全的any会进行类型检测 let foo:unknown aaa//合法 foo 123 //合法 console.log(foo);//合法 console.log(foo.length); //非法 //类型缩小 if(typeof foo string){ console.log(foo.length); //合法 }TS类型: void类型 当函数没有返回值则返回void类型 function foo (num1:number,num2:number):void{console.log(num1num2)return undefined//null也可以return null } /* foo的类型是()void 表示是一个返回void的函数类型 const类型推导推导出来是字面量类型 const height 1.88 //1.88为heigth的类型1.88是字面量类型 const height:1.88 //等价于 */ const foo () {} //等价于 type FooType () void const foo:FooType (){}说明 1.可以返回null和undefined因为默认情况下null和undefined是所有类型的子类型。 2.方法没有返回值将得到undefined但是需要定义成void类型而不是undefined类型,否则将报错。 3.当基于上下文的类型推导推导出返回类型为void的时候并不会强制函数一定不会返回内容。(了解) let names:Arraystring [arr1,arr2] names.forEach((item,index,arr){return 123;//没有意义但是不会报错 })TS类型never类型 几乎不用 开发中很少使用never类型 never表示永不存在的值 ①函数抛出异常函数不会执行完毕并返回 ②函数中执行无限循环的代码使得程序永远无法运行到函数返回值那一步永不存在返回。 新版本已经修改类型推导出来是void function foo(){ while (true) {} } function bar(){throw new Error() }never的使用场景 //封装工具/框架 function handleMessage(message: string | number ) {switch (typeof message) {case string:console.log(string处理方式处理message)breakcase number:console.log(number处理方式处理message)breakdefault:const check: never message //这一步永远来不到} }handleMessage(abc) handleMessage(123) //另外一个人调用这个函数传入布尔类型函数定义参数部分添加boolean类型check:never位置报错就会发现case少了一个布尔类型TS类型Tuple(元组) 元组类型表示一个已知元素数量和类型的数组(固定长度和类型的数组)各元素的类型不必相同。 数组中通常建议存放相同类型的元素不同类型的元素是不推荐放在数组中。如果不同类型放在数组中取值时并不清楚每个元素的具体类型。 使用元组类型的好处 1.元组数据结构中可以存放不同的数据类型取出来的item也有明确的类型 2.减少对象key的使用 let x: [string, number] [hello, 10]; console.log(x[0])//类型推导:(string|numbner)[] 取值并不清楚每一个元素是什么类型 let y [hello,10]使用场景:当函数需要返回多个值的时候 function useStateT(state: T) {// T 泛型let currentState stateconst changeState (newState: T) {currentState newState}const tupple: [T, (newState: T) void] [currentState, changeState]return tupple //返回值为[参数,函数] }const [counter, // numbersetCounter // (newState: number) void ] useState(10)setCounter(1000)const [title, // stringsetTitle // (newState: string) void ] useState(abc)const [flag, // booleansetFlag // (newState: boolean) void ] useState(true)语法细节 1.联合类型 | 和交叉类型 联合类型取值可以为多种类型中的一种使用 | 分隔每个类型 交叉类型: 一般用于多种对象类型取交集 使用 分隔 let myFavoriteNumber: string | number; myFavoriteNumber seven; // OK myFavoriteNumber 7; // OK说明 1.联合类型中的每一个类型被称之为联合成员union’s members 2.通常配合缩小联合一起使用 function printId(id:number|string){if(typeof id string){//缩小范围}else{} }交叉类型使用场景 interface Person {name:stringage:number } interface Fans {name:stringlike:string } const Women :PersonFans {name:ranran,age:18,like:study }2.type和interface接口作为类型声明 type 用于定义类型别名 (type alias) //使用type声明对象 type IDType string | number | boolean //分号和逗号可以 type PointType {x: number,y: number} type PointType {x: number;y: number}type PointType {//换行可以省略分号因为js中换行会自动添加分号x: numbery: number }接口可以看成规则,实现接口就必须满足接口设置的规则 语法 interface 接口名 //使用借口来声明对象 interface PointType{x:numbery:number } interface PointType{z:number } //多次声明需要都满足 const obj:myInterface {//obj对象必须满足接口的规则有name和agex:1,y:2,z:3 }类型别名与接口的区别 -相同点不同点别名1.类型别名和接口非常相似在定义对象类型时大部分时候可以任意选择使用。 2.接口中几乎所有的特性都可以在type中使用1.使用范围更广2.不允许同名声明两次(报错)接口1.只能声明对象2.可以多次声明同一个接口名称属性叠加 开发常用:其他数据类型常用type对象常用interface因为可扩展性更强 接口的继承extends 接口支持多继承 interface Person {name:stringage:number } interface Fans extends Person{like:string }3.类型断言 as 和非空类型断言 类型断言TypeScript 无法获取具体的类型信息但是开发员自己清楚就可以显式告诉TS 非空类型断言: !表示在此处告诉编译器不会为null和undefined // message - undefined | string function pringMessage(message?: string) {console.log(message!.length) //显式告诉不为空如果不这样写会报错因为message可能为空 }pringMessage(Hello World) pringMessage()4.字面量类型和类型缩小 可以联合多个类型类似于枚举的作用 //left right center分别是一个字面量 type Alignment left | right | center let align:Alignment //从上述字面量中选择一个字面量本身就是string类型所以对象在进行推理时会把options里的属性推理为string类型 type Method GET | POST type requestInfo {url: stringmethod: Method }//其他细节 function request(url: string, method: Method) {} //报错的情况 const options {url: http://www.coderwhy.org/abc,method: POST // 类型推导推导出来 options.method 是 string 类型} request(options.url, options.method) // 第二个参数报错 options.method 123 // 存在安全隐患 //解决方案1,优选 const options: requestInfo {url: http://www.coderwhy.org/abc,method: POST } //解决方案2:进行类型断言(但是不方便别人维护时阅读) request(options.url, options.method as post) //解决方案3:设置options的时候就确定类型 const options:{url:string,methond:POST} {url: http://www.coderwhy.org/abc,method: POST }//解决方案4:tips写法 const options {url: http://www.coderwhy.org/abc,method: POST } as const //把属性变成字面量,仅读request(options.url, options.method)类型缩小: 变量有一个确定的类型在使用时对其类型做更小的类型限制使得代码更加安全 typeof平等缩小(一些等号相关) instanceofin(用于确定对象是否具有带名称的属性,如果指定的属性在指定的对象或其原型链中则in 运算符返回true)… // 1. typeof 的类型缩小 type IDType number | string function printID(id: IDType) {if (typeof id string) {console.log(id.toUpperCase())} else {console.log(id)} }// 2. 平等的类型缩小 ! !/switch type Direction left | right | top | bottom function printDirection(direction: Direction) {//下面这串代码可以省略了//1. if 判断// if (direction left) {// console.log(direction)// } else if() {}// 2. switch 判断// switch(direction) {// case left:// console.log(direction);// break// case ...// } }// 3. instanceof function printTime(time: string | Date) {if (time instanceof Date) {console.log(time.toUTCString())} else {console.log(time)} }class Student {studying() {} }class Teacher {teaching() {} }function work(p: Student | Teacher) {if (p instanceof Student) {p.studying()} else {p.teaching()} }// 4. in interface Fish {swimming: () void } interface Dog {running: () void }function walk(animal: Fish | Dog) {if (swimming in animal) { //不能用.运算符时可以考虑inanimal.swimming()} else {animal.running()} }const fish:Fish {swimming() {console.log(swimming)} } 5.函数的类型和函数签名 函数表达式 编写函数类型的表达式Function Type Expressions来表示函数类型 函数类型表达式(参数列表) 函数返回值类型 function calc(n1: number,n2: number,fn: (num1: number, num2: number) number ) {return fn(n1, n2) }const result1 calc(20, 30, function (a1, a2) {return a1 a2 }) console.log(result1) // 50//这里虽然只传入一个参数但是不会报错 const result2 calc(20, 30, function (a1) {return a1 //因为只使用了一个参数所以可以只传入一个参数 })console.log(result2) // 600对于传入为函数类型的参数当实参小于形参时不会报错会自动省略多余形参 可以想象匿名参数forEach使用时并不是所有形参都传进去了 函数调用签名:支持声明属性 函数本身可以调用并且函数也是一个对象是对象就有属性。 格式(参数列表):返回值类型 用于对象内 作用描述带谁能够的函数可以在一个对象类型中写一个签名签名的作用是表示这是一个函数可以被调用 interface Bar{name:string } //不会报错 const bar:Bar (num1:number):number {return 123 } //调用时报错此表达式不可调用因为bar的类型是Bar并不知道其是一个函数可以被调用 bar()//函数调用签名 interface Bar{name:string(num1:number):number } const bar:Bar (num1:number):number {return 123 } bar(123)如果仅描述一个函数可以被调用使用函数表达式。如果在描述函数作为对象可以被调用同时也有其他属性时使用函数调用签名。 构造签名(理解) JavaScript函数也可以使用new操作符调用当被调用时TS会认为这是一个构造函数因为产生了一个新的对象。 function foo(){ } //可以new 但是不知道f的类型会推断f为any const f new foo()//问题:如何表达fn是一个构造函数不是一个普通函数 function factory(fn){return new fn() } //解决:使用构造函数签名 class Person{ } interface ICTORPerson{//符合当前规则的函数就是构造函数可以通过newnew():Person //new调用后的返回值是Person的示例相当于这个函数new了之后返回Person示例 } function factory(fn:ICTORPerson){const f new fn()return f } factory(Person)6.函数的重载和this类型 函数的重载(通用库和工具中使用较多) 函数的重载函数的名称相同但是参数不同的几个函数就是函数的重载 实现需求: 如果我们编写了一个add函数希望可以对字符串和数字类型进行相加 解决办法: 编写不同的重载签名overload signatures来表示函数可以以不同的方式进行调用 //需求:如果我们编写了一个add函数希望可以对字符串和数字类型进行相加//错误写法type AddType number | stringfunction add(a1: AddType, a2: AddType) {return a1 a2 //报错AddType和AddType类型不能相加}/*写法1联合类型的缺点1.进行很多逻辑判断2.返回值的类型不能确定*/function add(a1: number | string, a2: number | string) {if (typeof a1 number typeof a2 number) {return a1 a2} else if (typeof a1 string typeof a2 string) {return a1 a2}}实现方法:一般是编写两个或者以上的重载签名再去编写一个通用的函数以及实现 调用时根据传入的参数类型决定执行函数体时执行哪一个函数的重载签名 注意点: 重载签名没有函数体卸载通用函数之前通用函数不能被调用 //1.2一起构成函数重载 //1.重载签名不需要函数体 function add(num1: number, num2: number): number function add(num1: string, num2: string): string //2.通用的函数实现 通用函数不能被直接调用 function add(a1: any, a2: any) :any{return a1 a2 }联合类型和函数重载都可以实现一个功能时优先选择联合类型联合类型不能实现时再选择函数重载 this类型(很少使用) 没有对js进行特殊配置时this的默认类型是any const info {name: why,eating() {console.log(this.name eating)}}info.eating()function foo(){console.log(this)}foo()tsc --init 初始化配置文件tsconfig.json 当这个参数为true时TypeScript会根据上下文推导this但是不能正确选择时就会报错需要明确指定this的类型。 指定规则: 函数的第一个参数参数名必须是this,其他参数从第二个开始传递编译成js代码是第一个参数会被删除。 //this配置:没有模糊不明确(比如any所以配置之后上述代码会报错)的this noImplicitThis:true//显式指定this的类型将this作为函数的第一个参数名字必须是this type ThisType { name: string } function eating(this: ThisType, message: string) {console.log(this.name eating, message) } const info {name: why,eating } // 显式绑定 eating.call({ name: kobe }, 呵呵呵) eating.apply({ name: james }, 嘿嘿嘿 ) this相关的内置工具(了解) TypeScript提供一些工具类来辅助进行常见的类型转换这些类可以全局使用。 ThisParameterType用于提取一个函数类型Type的this参数类型没有this参数返回unknownOmitThisParameter移除Type的this参数类型并返回当前的函数类型ThisType用于绑定上下文的this类型(piana里的getters和action讲的很奇怪先记下来) type ThisType { name: string }function eating(this: ThisType, message: string) {console.log(this.name eating, message)}//获取函数eating的类型:type ty (this: ThisType, message: string) void type ty typeof eating //提取出函数里面this的类型type eatingThisType {name: string;} type eatingThisType ThisParameterTypety //type pureEatingType (message: string) void type pureEatingType OmitThisParametertyinterface IState{name:string,age:number } interface IStore{state:IState,eatting?:()void, } //给store绑定上下文this到IState const store:IStore ThisTypeIState {state:{name:ranran,age:18},eatting:function(){console.log(this.name)//如果没绑定获取到的应该是store的this里面没有name属性需要使用this.state.name获取。当很多函数使用到this.state里面的属性时代码会很冗余,将store的this绑定到IState之后this就从state里面取name。} }7.函数的参数 必传参数 - 有默认值的参数 - 可选参数 可选参数 使用指定某个参数是可选的类似于可选属性 //可选参数的类型:number | undefined //y - undefined | number function foo(x: number, y?: number) {console.log(x, y) } foo(20, 30) foo(20)默认参数 有默认值的情况下类型注解可以省略有默认值的参数是可以接受undefined类型不写时相当于传入了undefined当ts发现接受到undefined就给参数赋默认值了解即可使用时认为是指定的不是联合的 // 必传参数 - 有默认值的参数 - 可选参数 function foo(x: number, y: number 100) {console.log(x, y) } //省略类型注解的情况 function foo(x: number, y 100) {console.log(x, y) }foo(20) // 20 100剩余参数 剩余的参数会被封装成一个数组 function sum(initalNum: number, ...nums: number[]) {let total initalNumfor (const num of nums) {total num}return total }console.log(sum(20, 30)) console.log(sum(20, 30, 40)) console.log(sum(20, 30, 40, 50))TypeScript 类的使用 类的特性 ES6的class可以看作只是一个语法糖,看成构造函数的另一种写法所以类可以看成是一个有构造签名的函数。 //案例1 class Point{} typeof Point //function Point Poin.prototype.constructor //true //案例2 类可以看成是一个有构造签名的函数 class Person{}; //表示stor是一个函数类型并且是一个构造函数 function factory(stor: new() void){} factory(Person) //案例2的写法2 class Person{}; interface ty{new():void } //表示有构造签名的 function factory(stor: ty){} factory(Person)static静态属性(方法)/类属性(方法):不需要创建实例就可以使用是属于类的通过类名.属性(方法)调用实例属性(方法)是属于实例化出的这个对象通过对象.属性(方法)调用类的所有方法都定义在类的prototype属性上实例属性除非显式定义在本身(this)其余都是定义在原型上 1.成员属性必须先声明 class Person{//1.成员属性必须要先声明name:string ; //可以类型注解和设置初始化值age:numberconstructor(name:string,age:number){this.name namethis.age age} } const p1 new Person(ranran,18) const p2 new Person(biubiu,18)2. 类的成员修饰符 成员修饰符描述范围public(默认值)属性为共有属性任意位置访问和修改protected属性为保护属性此类和其子类中(子类实例也不可以)访问和修改private属性为私有属性只能在此类里访问和修改 3.可见修饰符的构造器语法糖(参数属性) TypeScript提供特殊的语法参数属性: 可以将构造函数参数转换成一个同名同值的类属性 1.创建声明同名的成员属性 2.可见修饰符修饰成员属性(权限 | readonly //完整写法 class Person{public name:string; constructor(name:string){this.name name;} } //简洁写法 class Person{constructor( public name:string){this.name name;} }4.在TypeScript可以使用存取器使私有属性被外界访问 get 属性名(){} 表示getter方法,在属性被读取时自动调用set 属性名(){} 表示setter方法在属性被修改时自动调用 class Person{private _name:string; //私有属性:属性前面使用_习惯约定如果没有写下划线在读取/修改该属性时并不知道访问的是属性name还是方法nameconstructor(name:string){this._name name;}get name(){return this._name}set name(value){this._name value;} } const per new Person(ranan); console.log(per.name);//读取属性自动调用get name(){} per.name biubiu; //修改属性set name(){}5.成员修饰符readOnly只读 readonly属性:表示该属性只读不可以修改和static连用需要放在其后面 class Person{name:ranan //定义实例属性readonly age:15 //定义只读属性call(){} //定义实例方法 }6.TS类型检测:鸭子类型 TS类型检测:鸭子类型(走得像鸭子声音像鸭子就是鸭子) 鸭子类型:只关心属性和行为是否一样并不关心是不是具体对应的类型 //情况1:不会被报错 makeArea({getArea:(){}}) //情况2 class A {name:ranran } class B{name:ranran } const a:A new B();抽象类abstract 抽象类:多个方法有共同方法但是实现方式有差别。可以将同名方法抽离到父类由子类去实现抽象方法 abstract修饰类 - 抽象类 抽象类不能被实例化只能被继承抽象类中可以有抽象方法也可以有普通方法 abstract修饰方法 - 抽象方法 抽象方法只能被定义在抽象类中,子类必须重写抽象类抽象方法没有方法体 //多态的体现:父类的引用指向子类 function makeArea(shape: Shape) {return shape.getArea() }abstract class Shape { //抽象类abstract getArea() //抽象方法 }class Rectangle extends Shape {private width: numberprivate height: numberconstructor(width: number, height: number) {super()this.width widththis.height height}getArea() {return this.width * this.height} }class Circle extends Shape {private r: numberconstructor(r: number) {super()this.r r}getArea() {return this.r * this.r * 3.14} }const rectangle new Rectangle(20, 30) //此时makeArea方法的形参是Shape的子类 console.log(makeArea(rectangle))const circle new Circle(10) console.log(makeArea(circle))TypeScript对象类型 ?可选属性readonly 只读属性 class Person{name?:ranranreadonly age:15}索引签名 索引签名:可以通过索引访问[标识符自己起:通过什么索引访问]:索引访问之后返回值的类型 使用场景:不知道具体的实现是什么样的但是知道具备某种特性 说明 一个索引签名属性的类型必须是string或者number其中一个数字类型索引的类型必须是字符串类型索引的子类型 原因:所有数字类型访问索引时最终都是转换为string类型访问的如果同时设置了数字类型0拿到的类型需要符合字符串类型’0’拿到的类型 //案例1 interface IndexLanguage {[index:number]:string //通过number索引访问访问之后返回string类型数据//这里定义的属性也得满足索引签名的要求//如果需要两种类型需要分开写(语法不支持)[index:string]:string } function getInfo():IndexLanguage {} //不知道具体的实现是什么样的但是知道具备某种特性 const frontLanguage getInfo()//案例2 interface IPerson {//告知通过索引获取到的数据类型是什么样[index:string]: string } //报错原因 [biu,ranran]通过字面量创建的Array实例 数组中自带了很多其他属性比如name.forEach返回值是Function不是string const name:IPerson [biu,ranran]函数签名 interface来定义对象中普通的属性和方法的实际上它也可以用来定义函数类型(除非特别的情况推荐使用类型别名来定义函数) // type CalcFn (n1: number, n2: number) number// 可调用接口 interface CalcFn {(n1: number, n2: number): number }function calc(num1: number, num2: number, calcFunc: CalcFn) {return calcFunc(num1, num2) }const add: CalcFn (num1, num2) num1 num2 calc(20, 30, add) TypeScript接口 类实现接口 implements 接口可以看成规则对类进行约束 说明 接口只定义对象的结构而不考虑实际值在接口中所有的方法都是抽象方法 定义类时可以使类去实现一个接口(满足接口定义的规则)一个子类只能有一个父类但是可以实现多个接口 interface myInterface{ //接口定义必须有name和sayHelloname:string,sayHello():void; } class MyClass implements myInterface{name:stringconstructor(name:string){this.name name;}sayHello(){} //类的实现 }抽象类和接口的区别 区别抽象类接口继承抽象类是类一个类只能继承一个抽象类一个类可以实现多个接口方法可以是普通方法和抽象方法全是抽象方法子类子类必须覆盖抽象类的抽象方法子类必须遵守接口定义的规则接口中的所有东西都得有 抽象类是对类本质的抽象表达的是 is a 的关系。比如male is a Human。抽象类包含并实现子类的通用特性 接口是对行为的抽象表达的是 like a 的关系。比如Baoma like a plane它有飞的功能一样可以飞但其本质上 is a Car。接口的核心是定义行为即实现类可以做什么 特殊:严格字面量赋值检测 第一次创建的对象字面量被表示为新鲜的对于新鲜的字面量会进行严格的类型检测(必须完全满足类型的要求不能有多余的属性)。 当一个新的对象字面量分配给一个变量或传递给一个非空目标类型的参数时对象字面量指定不存在的属性是错误的。 name: stringage: number }const p: IPerson { //第一次创建新鲜的被严格的检测name: why,age: 18,height: 1.88//报错Iperson接口没有height }const info { //第一次创建新鲜的被严格的检测name: why,age: 18,height: 1.88 } // freshness 不是新鲜的不严格检测 const p2: IPerson info // 不报错 TypeScript枚举类型 格式:enum 枚举类型标识符 {} enum Color {//没设置值初始值默认从0开始按顺序自增可以理解为数组下标RED,PINK,BLUEblue,//设置初始值 } const pink: Color Color.PINK; console.log(pink); // 1泛型 泛型语法的基本使用 泛型指是在定义函数或者类时并不知道类型在被使用时才知道数据的类型。 泛型可以指定多个定义泛型格式类。 T被称为类型变量type variableT作为参数泛化成具体类型的作用叫做类型参数化。 泛型也可以指定默认值 //定义泛型T定义的位置一般在标识符的后面 function fn T (a:T):T{return a; } fn(10); //此时T是number利用类型推断 const fn string(hello) //显式指定T是string为了方便阅读最好显式指定interface Inter{//定义接口length:number; } function fnT string(a:T):number{//这里的泛型必须继承Inter接口return a.length; } 泛型类的使用案例 class PointT {x: Ty: Tz: Tconstructor(x: T, y: T, z: T) {this.x xthis.y ythis.z z} }const p1 new Point(1.33.2, 2.22.3, 4.22.1) const p2 new Pointstring(1.33.2, 2.22.3, 4.22.1) const p3: Pointstring new Point(1.33.2, 2.22.3, 4.22.1)const names1: string[] [abc, cba, nba] const names2: Arraystring [abc, cba, nba] 泛型约束和类型条件 对泛型的类型进行约束 interface Inter{//定义接口length:number; } //写法1:这里的泛型继承Inter接口 //T相当于是一个变量用于记录本次调用的类型所以在函数执行周期中会保留参数的类型 function fnT extends Inter(a:T):number{return a; } const f fn(aaaa) //写法1便于TS推断f的类型为字符串 //写法2: function fn(a:Inter):Inter{//这里的泛型必须继承Inter接口return a; } const f fn(aaaa) //写法2会导致形参a的原始类型丢失推导f的类型为Interkeyof 和 in keyof 类型 接受一个对象类型作为参数返回该对象属性名组成的字面量联合类型in的右侧一般会跟一个联合类型使用in操作符可以对该联合类型进行迭代。 其作用类似JS中的for...in或者for...of //keyof使用案例 type Dog { name: string; age: number; }; type D keyof Dog; //type D name | age//in的使用案例 type Animals pig | cat | dog​ type animals {[key in Animals]: string } // type animals { // pig: string; //第一次迭代 // cat: string; //第二次迭代 // dog: string; //第三次迭代 // }keyof any返回联合类型string | number | symbol 补充遇见索引签名时keyof会直接返回索引的类型。索引类型为string时keyof返回的类型是string | number这是因为数字类型索引最终访问时也会被转换为字符串索引类型。 type Dog { [y:number]: number };type dog keyof Dog; //type dog number​type Doggy { [y:string]: boolean };type doggy keyof Doggy; //type doggy string | number使用场景与extends关键字结合使用对对象的属性做限定。 在泛型中使用的案例 // k extends name| age 这里的extends表示k是不是其中一个联合类型 function getObjectPropertyO,K extends keyof O(obj:O,key:K){return obj[key] } const info {name:ranran,age:18 }getObjectProperty(info,name)TypeScript映射类型(开发中很少用用于封装组件) 映射类型:可以理解为将一个类型映射成一个新的类型 使用场景一个类型需要另一个类型但是又不想拷贝(映射)一份可以考虑使用映射类型。 可以将映射类型想象成一个函数函数的作用就是拷贝(映射)类型 //映射类型MapPerson //定义泛型接收需要拷贝的类型 type MapPersonType {//[index:number]:any //索引签名写法//Property自定义的标识符 keyof Type表示联合类型in从联合类型中依次取值赋值给Property[Property in keyof Type]:Type[Property] } interface Iperson{name:stringage:number }type NewPerson MapPersonIperson //使用映射类型拷贝Iperson类型映射类型修饰符 可能使用的两个类型 readonliy设置属性只读设置属性可选 可以通过前缀-或者删除或添加这些修饰符默认使用 //映射类型MapPerson //将所有属性映射为可选属性 type MapPersonType {//readonly [Property in keyof Type]:Type[Property]-readonly [Property in keyof Type] -?:Type[Property] }interface Iperson{name:stringage:number }type NewPerson MapPersonIperson /* type NewPerson {readonly name: string;readonly age: number; } */
http://www.pierceye.com/news/179518/

相关文章:

  • 礼品网站制作辽宁省建设部网站
  • 网站群的建设目标澧县网页设计
  • 邯郸网站建设在哪里网站建设yingkagou
  • 姜堰区网站建设企业公司网站制作
  • 目前做的比较好的法律网站有哪些兰州seo技术优化排名公司
  • wordpress网站接入qqwordpress调用二级分类目录
  • 自建站有哪些站点soho 网站建设
  • cms网站建设如果在网上接网站建设项目
  • 建设网站的重点与难点在于社区网站模版
  • 自己在线制作logo免费网站公司网页设计教程
  • 广西城乡建设网站一家企业如何做网站推广
  • 小程序可以做网站吗wordpress 活动插件
  • 深圳网站建设流程图货代网站制作
  • 建设一个网站需要什么技术人员在线音乐网站开发
  • 做现货黄金看什么网站网络服务商怎么查询
  • 英语作文网站紫色个人网站模板
  • 视频直播网站开发 设计网站做的文字乱码
  • 江苏省建设执业中心网站wordpress婚礼模板下载
  • 互联网网站开发html5怎么做网站可以注册的
  • 公司网站建设前期方案经典设计产品
  • 南昌市公司网站建设品牌建设浅谈
  • 网站实现留言功能吗制作视频用什么app
  • 聊城企业网站建设公司网页版wordpress教程视频
  • 网上购物的网站开发背景wordpress more标签使用教程
  • 多语言网站建设方案新建网站的价格
  • 企业网站服务器的选择企业网站建设市场分析
  • 阜阳做网站的公司网页制作自学教程
  • 阿里巴巴吧网站怎么做网页设计师属于什么部门
  • 望京网站建设公司红酒专业网站建设
  • 兰州市城市建设设计院网站游戏网站搭建需要多少钱