TypeScript快速上手
📚一、TypeScript简介
1.TypeScript由微软
开发,是其于JavaScript的一个扩展语言
.
2.TypeScript包含了JavaScript的所有内容,即:TypeScript是JavaScript的超集
3.TypeScript增加了:静态奖型检查、接口、泛型等很多现代开发特性
,因此吏适合大型项目
的开发。
4.TypeScript需要编译
为JavaScript,然后交给浏览器成其他JavaScript运行环境执行
📚二、为何需要ypeScript
1️⃣今非昔比的JavaScript(了解)
- JavaScript当年诞生时的定位是浏览器
脚本语言
,用于在网页中嵌入一些简单的逻辑
而且代码量很少. - 随着时间的推移,JavaScript变得越来越流行,如今的JavaScript已经可以
全栈编程
了. - 现如今的JavaScript
应用场景
比当年丰富
的多,代码量
也比当年大
很多,随便一个JavaScript项目的代码量,可以轻松的达到几万行,甚至十几万行1 - 然而JavaScript当年
出生简陋
,没考虑到如今的应用场景和代码量,逐渐的就出现了很多困扰
2️⃣JavaScript中的困扰
😔1,不清不楚的数据类型
let welcome = 'hello'
welcome()/此行报错:TypeError:welcome is not a function
😔2.有漏涧的逻辑
const str = Date.now() % 2 ? '奇数' : '偶数'
if (str !== '奇数') {alert('hello')
} else if (str === '偶数') {alert('world')
}
😔3.访问不存在的属性
const obj = {width:10,height:15 }
const area = obj.width * obj.heigth;
😔4.低级的拼写错误
const message ='hello,world'
message.toupercase()
3️⃣『静态类型检查』
- 在代码运行前进行检查,发现代码的错误或不合理之处,减小运行时异常的出现的几率,此种检查叫『
静态类型检查
』,TypeScript和核心就是『静态类型检查』,简言之就是把运行时的错误前置
。 - 同样的功能,TypeScript的代码量要
大于
JavaScript,但由于TypeScript的代码结构更加清晰,在后期代码的维护中TypeScript却远胜于
JavaScript。.
📚三、编译TypeScript
浏览器不能直接运行TypeScript代码,需要编译为JavaScript再交由浏览器解析器执行。
🔖1.命令行编译
要把
.ts
文件编译为.js
文件,需要配置TypeScript
的编译环境,步骤如下:
- 第一步:创建一个
demo.ts
文件,例如:
const person = {name: '李四',age: 18
}console.log(`我叫${person.name},我今年${person.age}岁了`)
- 第二步:全局安装
TypeScript
npm i typescript -g
- 第三步:使用命令编译
.ts
文件
tsc demo.ts
🔖2.自动化编译
- 第一步:创建
TypeScript
编译控制文件
tsc --init
- 第二步:监视目录中的
.ts
文件变化
tsc --watch
- 第三步:小优化,当编译出错时不生成
.js
文件
tsc --noEmitonError --watch
📚四、类型声明
使用:
来对变量
或函数形参
,进行类型声明:
let a:string //变量a只能存储字符串
let b:number //变量b只能存储数值
let c:boolean //变量c只能存储布尔值
a = 'hello'
a = 100 //警告:不能将类型“number'”分配给类型“string”b = 666
b = '你好' //警告:不能将类型“string”分配给类型“number'”c = true
c = 666 //警制:不能将类型“number”分配给类型“boolean”//参数x必须是数字,参数y也必须是数字,函数返回值也必须是数字
function demo(x:number,y:number):number{return x + y
}demo(100,200)demo(100,'200') //警告:类型“string”的参数不能赋给类型“number”的参数demo(100,200,300) //警告:应有2个参数,但获得3个demo(100) //警告:应有2个参数,但获得1个
在:
后也可以写字面量类型
,不过实际开发中用的不多
1et a:'你好' //a的值只能为字符串“你好”
1et b:100 //b的值只能为数字180
a = '欢迎' //警告:不能将类型"欢迎"”分配给类型"你好"”
b = 200 //警告:不能将类型“200”分配给类型“100”
📚五、类型推断
📚六、类型总览
let str1:string
str1 = 'hello'
str1 = new String('hello') //报错
let str2:String
str2 = 'hello'
str2 = new String('hello')
console.log(typeof str1)
console.log(typeof str2)
//原始类型字符串
let str = 'hello';
//当访问str.length时,Javascript引擎做了以下工作:
let size = (function () {//1.自动装箱:创建一个临时的string对象包装原始字符串let tempstringobject = new String(str);//2.访问String对象的length,属性let lengthvalue = tempstringobject.length;//3,销毁临时对象,返回长度值//(JavaScript引擎自动处理对象销毁,开发者无感知)return lengthvalue;
})()
console.log(size); //输出: 5
📚七、常用类型
🔖1.any
//明确的表示a的类型是any 一 【显式的any】
let a: any
//以下对a的赋值,均无警告
a = 100
a = '你好'
a = false//没有明确的表示b的类型是any,但TS主动推断出来b是any 一 隐式的any
let b
//以下对b的赋值,均无警告
b = 100
b = '你好'
b = false
/*注意点:ay类型的变量,可以赋值给任意类型的变童*/
let c: any
c = 9
let x: string
x = c //无警告
🔖2.unknown
//设置a的类型为unknown
let a: unknown//以下对a的赋值,均正常
a = 100
a = false
a = '你好'// 设置x的数据类型为string
let x: string
x = a//警告:不能将类型“unknown'”分配给类型“string”
// 设置a的类型为unknown
let a: unknown
a = 'hello'// 第一种方式:加类型判断
if (typeof a === 'string') {x = aconsole.log(x)
}// 第二种方式:加断言
x = a as string//第三种方式:加断言
x = <string>a
let str1: string
str1 = 'hello'
str1.toUppercase() //无警告let str2: any
str2 = 'hello'
str2.toUpperCase() //无警告let str3: unknown
str3 = 'hello';
str3.toUpperCase(); //警告:“str3”的类型为“未知”// 使用断言强制指定str3的类型为string
(str3 as string).toUpperCase()//无警告
🔖3.never
/*指定a的类型为never,那就意味着a以后不能存任何的数据了*/
let a: never//以下对a的所有赋值都会有警告
a = 1
a = true
a = undefined
a = null
//指定a的类型为string
let a:string
//给a设置一个值
a = 'hello'if (typeof a ==='string') {console.log(a.toUppercase())
}else{console.log(a) //Typescript会推断出此处的a是never,因为没有任何一个值符合此处的逻辑
}
//限制throwErrori函数不需要有任何返回值,任何值都不行,像undeifned、null都不行
function throwError(str: string): never {throw new Error('程序异常退出:' + str)
}
🔖4.void
function logMessage(msg:string):void{
console.log(msg)
}
logMessage('你好')
//无警告
function logMessage(msg: string): void {console.log(msg)
}//无警告
function logMessage2(msg: string): void {console.log(msg)return;
}//无警告
function logMessage3(msg: string): void {console.log(msg)return undefined
}
function logMessage(msg: string): void {console.log(msg)
}let result = logMessage('你好')if (result) { //此行报错:无法测试"void"类型的表达式的真实性console.log('logMessage有返▣值')
}
function logMessage(msg: string): undefined {console.log(msg)
}let result = logMessage('你好')if (result) { //此行无警告console.log('logMessage?有返回值')
}
🔖5.object
🔖🔖object(小写)
let a:object //a的值可以是任何【非原始类型】,包括:对象、函数、数组等//以下代码,是将【非原始类型】赋给a,所以均符合要求
a = {}
a = {name: '张三'}
a = [1, 3, 5, 7, 9]
a = function () {}
a = new String('123')
class Person {}
a = new Person() //以下代码,是将【原始类型】赋给a,有警告
a = 1 //警告:不能将类型“number”分配给类型“object”
a = true //警告:不能将类型boolean'”分配给类型“object'
a = '你好' //警告:不能将类型“string”分配给类型“object'”
a = null //警告:不能将类型“nul1”分配给类型“object”
a = undefined //警告:不能将类型“undefined”分配给类型“object”
🔖🔖Object(大写)
let b: Object //b的值必须是Object的实例象(像法undefined和nul1的任何值)//以下代同,均关警否,因为格就的值,都是0bCct的实例对参
b = {}
b = {name: '张三'}
b = [1, 3, 5, 7, 9]
b = function () {}
b = new String('123')
class Person {}
b = new Person()
b = 1 //1不是陆0t的实刷对象,国风想装对象是Object的实例
b = true //true不是Object的实例对象,但其在钻对整是Object的实例
b = '你好' //“你好”不是Object的实例对象,阳其随酒象是Object的实例//以下代码均有警告
b = null //警告:不能将类型“nu11”分配给类型“object”
b=undefined //警告:不能将类型“undefined”分配给类型“object”
🔖🔖声明对象类型
🔖🔖声明函数类型
🔖🔖声明数组类型
🔖6.tuple
🔖7.enum
编译后生成的JavaScript代码量较大:
"use strict";
var Directions;
(function (Directions) {Directions[Directions["Up"] = 0] = "Up";Directions[Directions["Down"] = 1] = "Down";Directions[Directions["Left"] = 2] = "Left";Directions[Directions["Right"] = 3] = "Right";
})(Directions || (Directions = {}))
let x = Directions.Up;
使用常量枚举的TypeScript代码如下:
const enum Directions {Up,Down,Left,Right
}let x = Directions.Up;
编译后生成的JavaScript代码量较小:
"use strict";
let x = 0 /* Directions.Up */
🔖8.type
🔖9.一个特殊情况
官方文档的说明:👉Assignability of Functions
🔖10.复习类相关知识
本小节是复习类相关知识,如果
有相关基础可以跳过
。
类 class,Person类
class Person {//属性声明name: stringage: number//构造器constructor(name: string, age: number) {this.name = namethis.age = age}//方法speak() {console.log(`我叫:${this.name},今年${this.age}岁`)}
}//Person实圆
const p1 = new Person('周杰伦', 38)
Student继承Person
class Student extends Person {grade: string//构造器constructor(name: string, age: number, grade: string) {super(name, age)this.grade = grade}//备注本例中若Student:类不需要额外的属性,Student的构造器可以省略
//重写从父类继承的方法override speak() {console.log(`我是学生,我叫:${this.name},今年${this.age}岁,在读${this.grade}年级`)}//子类自己的方法study() {console.log(`{this.name}正在努力学习中....`)}
}
🔖11.属性修饰符
🔖🔖public修饰符
class Person {//name写了public修饰符,age没写修饰符,最终都是public修饰符public name: stringage: numberconstructor(name: string, age: number) {this.name = namethis.age = age}speak() {// 类的【内部】可以访问public修饰的name和ageconsole.log(`我叫:${this.name},今年${this.age}岁`)}
}const p1 = new Person('周杰伦', 38)
//类前【外部】可以访问public修饰的属性
console.log(p1.name)
🔖🔖属性的简写形式
简写前
简写后
🔖🔖protected修饰符
🔖🔖private饱饰符
这个图片下面还有一点没有截到。
🔖🔖readonly修饰符
这个图片下面还有一点没有截到。
🔖12.抽象类
🔖13.interface
🔖🔖定义类结构
🔖🔖定义对象结构
🔖🔖定义函数结构
🔖🔖接口之间的继承
🔖🔖接口自动合并(可重复定义)和总结
🔖14,一些相似概念的区别
🔖🔖14.1.interface与type的区别
🔖🔖14.2,interface与抽象类的区别
📚八、自定义类型
📚九、类型声明文件