typescript 概述 typescript 变量与数据类型 列出 javascript 中没有的地方
官网在此:typescript中文网
TypeScript(简称:TS)是 JavaScript 的超集(JS 有的 TS 都有)。 TypeScript = Type + JavaScript(为 JS 添加了类型系统)。 TypeScript 是微软开发的开源编程语言,设计目标是开发大型应用。 可以在任何浏览器、任何计算机、任何操作系统上运行。
安装:
首先拥有 node 环境全局安装 typescript (npm i typescript -g)检测 typescript 是否安装成功 (·终端输入:tsc·)运行:
首先将 ts 代码转换成 js 代码,再运行 js 代码 (tsc 1.ts ; node 1.js )安装转换器 (npm i ts-node -g);然后直接运行 ts 代码 (ts-node 1.ts)(内部原理也是将 ts 装换成 js)ts 中的变量与 js 中的变量使用基本一致,只是在原有基础上增加了:类型注释(声明变量前要声明其类型)
注意:声明变量的时候要指定变量的类型。
其中 number 就是 类型注解
类型注解的作用类型注解:是一种 为变量添加类型约束 的方式
程序员 和 TS 有个约定
// 程序员 和 TS 约定:变量 age 的类型为 number(数值类型) let age: number = 18约定了什么类型,就只能给变量赋什么类型的值
// × 错误演示 age = 'Hello TS'只要类型确定,变量就拥有了该类型的 属性和方法
①:简单数据类型的类型注解
let num :number = 18 let str :string = '18' let current : boolean = true let find : undefined = undefined let state : null = null②:对象类型的类型注解
对于对象类型的类型注解,就要用到接口(为对象的类型注解命名,并为你的代码建立契约来约束对象的结构)
// 用接口定义公共的类型注解(每个成员间可用分号';' 隔开,也可省略) interface IUser{ name:string age:number say:(talk:string)=>void //无返回值就返回 void(空);存在返回值,就返回对应的数据类型注解 } // 用类型注解规范对象 ‘chen’ let chen : IUser = { name:'cwen', age:18, say:function(hello){ console.log(hello) } }interface 表示接口,接口名称约定以I开头
接口可以继承接口
接口的继承,类实现接口 interface People{ work():void } interface Cwen extends People{ //用extends 实现接口的继承 play(name:string):void } class Web implements Cwen{ // 用web 类 实现接口的方法(继承后,接口有两个方法,需要继承) public name:string constructor(name:string){ this.name = name } work():void{ console.log( this.name+'敲代码') } play(name):void{ console.log(name + '玩游戏') } } var w = new Web('陈稳') w.play('陈稳') w.work() 接口的继承,类实现接口,类再继承类 interface People{ work():void } interface Cwen extends People{ //用extends 实现接口的继承 play(name:string):void } class Programer{ public name:string constructor(name:string){ this.name = name } coding(code:string):string{ return this.name + code } } class Web extends Programer implements Cwen{ // 用web 类 实现接口的方法(继承后,接口有两个方法,需要继承) constructor(name:string){ super(name) } work():void{ console.log( this.name+'敲代码') } play(name):void{ console.log(name + '玩游戏') } } var w = new Web('陈稳') console.log(w.coding('敲代码'))typescript 语法与 javascript 语法基本一致,只是在定义变量时,要进行类型注解
typescript 中函数定义及使用与 javascript 一致,只是在定义形参时,可以用类型注解来规范形参的类型;还可用类型注解规范函数的返回值
function play(age: number): void { if (age < 18) { return } console.log('网吧上网好爽啊,王者、吃鸡两不误') } play(16) // 情况1:进入if后return,后续代码不执行 play(20) // 情况2:不进if,直接打印内容: 网吧上网好爽啊,王者、吃鸡两不误注意:如果函数没有返回值,默认返回值类型是:void(空),可省略不写
为了在浏览器运行 ts代码;需要将 ts 代码转换成 js 代码,然后在 HTML 页面引入使用;为了避免每次修改 ts 都要执行 tsc ;此处可也对 ts 代码的变化进行监控,然后实时更新。命令行:tsc --watch index.ts(–watch 表示启用监视模式,只要重新保存了 ts 文件,就会自动调用 tsc 将 ts 转化为 js)
typescript 操作 DOM BOM 的方式与 javascript 方式基本一致,所有 javascript 的 API 皆可使用
问题:通过 选择器获取 DOM 元素时,拿到的元素 类型都是 Element 原因:因为无法根据 选择器 来确定元素的类型,所以,该方法就返回了一个宽泛的类型:元素(Element)类型 不管是 h1 还是 img 都是元素 导致新问题:无法访问 img 元素的 src 属性了 因为:Element 类型只包含所有元素共有的属性和方法(比如:id 属性)
解决方法:使用 类型断言,来手动指定更加具体的类型(比如,此处应该比 Element 类型更加具体)
let img = document.querySelector('#image') as HTMLImageElement技巧:通过 console.dir() 打印 DOM 元素,在属性的最后面,即可看到该元素的类型
总结:对于 DOM 以及 BOM的操作,建议使用 javascript
枚举是组织有关联数据的一种方式
使用场景:当变量的值,只能是几个固定值中的一个,应该使用枚举来实现
注意:JS 中没有枚举,这是 TS 为了弥补 JS 自身不足而新增的
约定 枚举名称、成员名称以大写字母开头。 多个成员之间使用逗号 (,)分隔。 注意:枚举中的成员,根据功能自己指定; 枚举中的成员不是键值对
枚举是一种类型,因此,可以其作为变量的类型注解
enum Gender { Female, Male } let userGender: Gender访问枚举(Gender)中的成员,作为变量(userGender)的值:
userGender = Gender.Female userGender = Gender.Male注意:枚举成员是 只读 的,也就是说枚举中的成员 可以访问,但是不能赋值 !
枚举成员是有值的,默认为:从 0 开始自增 的数值
数字枚举:枚举成员的值为数字
当然,也可以给枚举中的成员初始化值
enum Gender { Female = 1, Male } // Female => 1 Male => 2 enum Gender { Female = 1, Male = 100 } // Female => 1 Male => 100字符串枚举:枚举成员的值是字符串
enum Gender { Female = '女', Male = '男' }注意:字符串枚举 没有自增长行为,因此,每个成员必须有初始值
console.log(Gender.Female) // 女 console.log(Gender.Male) // 男类的定义与 es6 中类的定义相似(具体可参考:es6中的类)
class Person { //定义基本的类 name: string //属性 前面省略了 public 关键字 constructor(name: string) { // 构造函数 实例化类的时候触发的方法 this.name = name } work():string{ return `${this.name} 在工作` } } // 类的使用 // var p = new Person('cwen') // console.log(p)类的继承用到 constructor super 关键字(与es6 中类的继承相似)
class Person { //定义基本的类 name: string //属性 前面省略了 public 关键字 constructor(name: string) { // 构造函数 实例化类的时候触发的方法 this.name = name } work():string{ return `${this.name} 在工作` } } // var p = new Person('cwen') // console.log(p) //# 类的继承 class Son extends Person{ constructor(name:string){ super(name) } work():string{ return '子类在工作' } }注意:当子类的方法与父类方法一致时,子类使用自身的方法
注意:修饰符既可以修饰属性,也可以修饰方法
静态方法,只能通过类来调用;实例方法必须用类的实例来调用
class Star{ public name:string static age:number constructor(name:string){ this.name = name } run():string{ // 实例方法 return this.name + '在奔跑' } static work():string{ //静态方法(静态方法只能使用静态属性) return Star.age + '在工作' } } // 实例方法的调用,直接用类调用 // Star.age = 21 // console.log(Star.work()) // 实例方法,必须new 实例来调用 // var sta = new Star('cwen') // console.log(sta.run())多态:父类定义一个方法不去实现,让继承他的子类实现,每一个子类都有不同的表现(多态属于继承)
class Animal{ public name:string constructor(name:string){ this.name = name } eat():void{ //定义方法,让子类来实现 console.log('动物都会吃') } } class Dog extends Animal{ // 定义dog 类,实现吃的方法 constructor(name:string){ super(name) } eat():string{ return this.name + '吃肉肉' } } class Cat extends Animal{ // 定义cat 类,实现吃的方法 constructor(name:string){ super(name) } eat():string{ return this.name + '吃咸鱼' } } // var c = new Cat('小百度') // console.log(c.eat())泛型:软件工程中,我们不仅要创建一致风格的API,同时也要考虑可复用性;组件不仅能支持当前数据类型,同时也能支持未来的数据类型,这在创建大型项目时提供了十分灵活的功能。通俗理解;泛型是解决:类、接口、方法的复用性。以及对 不特定数据类型的支持
对于一般的函数,类型注解是数字就只能传递数字,若要修改成字符串还要重新注解;此时我们可以用 any 来注解,那么问题来了, any注解后无法验证传入的参数是否合法。所以泛型就很好的解决了此问题(泛型:可以支持不特定的数据类型,要求:传入的参数和返回的参数数据类型一致)
//# 定义泛型的函数 (一般用 T ,用其他字符也可),具体什么类型是调用方法时决定的 function getNum<T>(value:T):T{ return value } console.log(getNum<number>(123))