一:基础语法库
非空判断操作符 (!) obj!.name obj绝对不是一个空的
1.静态类型的深度理解
const count : number = 123 //count就具备了number类型的方法
2.类型
①:基础类型:number、string、null、undefined、symbol、boolean、void、bigint
②:对象类型
//数组 const numbers: number[] = [1,2,3] 或者 const arr:Array<number> = [1,2,3] //元组 (tuple 和数组非常相似,只是把类型写着数组里面,少写或者多写都会报错 )可以调用push 但是push的类型只能是已经定义过的 let user:[string,number] = [18,'alhh'] //对象 const teacher:{ name:string } //类 class Person{} const lqq:Person = new Person
3.interface接口
对对象的形状(shape)进行描述,Duck Typing(鸭子类型)
interface Person { name:string, age?:number; } let alhh:Person = { name:'lqq' }
4.函数
如果一个函数返回为void,那么它可以返回null或者undefined
//约定输入,约定输出 可选参数后面不能再跟确定的参数 function add(x:number,y:number,z?:number):number{ return a +b }
interface描述函数类型
const sum = (x: number, y: number) => { return x + y } interface ISum { (x:number,y:number):number } const sum2:ISum = sum
3.类型注解和类型推断(type annotation & type inference)、联合类型
①:类型注解
let count: number //告诉ts变量是什么类型
②:类型推断
let countInference = 123 //ts会自动的去尝试分析变量的类型
③:联合类型 ( | )不确定是number还是string
let user : numer | string = 'alhh'
④:类型守卫
在联合类型中,不同的条件分支里面,智能的缩小范围,代码出错的几率就会降低(先判断是某种类型然后去做某事)
如果ts能够自动分析变量类型,就什么也不用做了,如果无法分析变量类型就需要类型注解了
例如在函数传参的时候 需要类型注解参数类型
4. class (封装、继承、多态)
①:抽象类只能继承不能实例化。他把共用的东西抽出来封装
ts接口也可以将通用的提炼出来,然后extends
protected:它在子类中式允许被访问的
②:类和接口
interface Radio { switchRadio(trigger:boolean):void } interface Battery { checkBatteryStatus(): void; } class Car implements Radio{ switchRadio(trigger:boolean){ } } class Cellphone implements Radio,Battery{ switchRadio(trigger:boolean){ }, checkBatteryStatus(): { }; } //或者 用一个接口继承Radio 然后cellphone去实现它 interface RadioWithBattery extends Radio{ checkBatteryStatus():void } class Cellphone implements RadioWithBattery{ switchRadio(trigger:boolean){ }, checkBatteryStatus(): { }; }
5.枚举(enum)
enum Direction{ Up, Down, Right, Left } console.log(Direction.up) //0 console.log(Direction[0]) //编译后 (function(Direction){ Direction[Direction["up"]=0] ="up" Direction[Direction["Down"]=1] ="Down" }(Direction||Direction={}))
常数枚举
const enum Color{ Red,Yellow,Blue } console.log(Color) //报错 console.log(Color[0]) //报错 console.log(Color.Red) //可以 //只能通过属性去调用,不能直接调用本身和通过索引去调用 //与普通枚举的区别是:它会在编译阶段删除,并且不能包含计算成员
6.泛型(Generics)
①:在定义接口、函数和类的时候,不预先指定具体的类型,而在使用的时候指定类型
function echo<T>(arg:T):T { return arg } //可以传多个值 (交换值) function swap<T,U>(tuple:[T,U]):[U,T]{ return [tuple[1],tuple[0]] } const result = swap(['string', 123])
②:泛型约束
在函数内部使用泛型变量时候,由于不知道是哪种类型,所以不能随意操作他的属性和方法
interface INumber{ length:number } function echoWithLength<T extends INumber>(arg:T):T{ return arg.length }
echoWithLength('str')
const result3 = echoWithLength({length: 10})
const result4 = echoWithLength([1, 2, 3])
③:泛型与类和接口
//类 class Queue<T>{ private data = [] push(item:T){ return this.data.push(item) } pop():T{ this.data.shift() } } const queue = new Queue() queue.push(1) queue.push('str') console.log(queue.pop().toFixed()) //可以像数组添加各种类型的值,但是在使用中就会出错,只有number类型有toFixed方法 修改加泛型 <T> 在类和方法上加 T const queue = new Queue<number>() //接口 interface KeyPair<T,U>{ key:T, value:U }
④:类型别名,字面量和交叉类型
//类型别名 type PlusType = (x:number,y:number) =>number let sum:PlusType //字面量 const str:'name' = 'name' //等于name2都会报错 const number:1 = 1 type Directions = 'Up' | 'Down' | 'left' | 'Right' let toWhere:Directions = 'Left' //交叉类型 interface IName{ name:string } type IPerson = IName & {age:number}
7.声明文件
declare var jQuery:(selector:string)=>any
8.内置类型
ts还提供了一些功能性,帮助性的类型,这些类型,在js世界是看不到的,叫utility type
//Partial可以把传入的类型都变成可选 interface IPerson{ name:string, age:number } let IPartial = Partial<IPerson> //返回的类型可以忽略传入类型的某个属性 type IOmit = Omit<IPerson,'name'>
9.null 和undefined
let x:number x = undefined //null和undefined是其他类型的子类型 //正常情况下不可以,但是可以通过设置中将 strictNullChecks 改为false 推荐写法 let x:number | undefined |null
10.never(永远不知道是什么类型)
//一个函数永远不会返回,那么它的返回类型就是never function sum:never{ while(true) } //如果一个函数一定抛出错误,那么它也永远不会正常结束 function error():never{ throw Error('出错了') }