前言
经过多年的全栈开发经验和多种编程语言的开发经验,编程语言的规范的重要性与日俱增
对未来的前端编程而言,typescript的比重相信一定会日新月异
所以这边对于TypeScript做一篇比较详细和完整的整理
日后也会逐渐更新和补充。
TypeScript目前版本:5.3
TypeScript官方网站传送门
如果您对前端技术感兴趣的话,可以订阅鄙人的Vue栏目
Vue栏目传送门
一、TypeScript的由来
2010 – 微软团队开始开发
2012 – 第一个公开版本发布(TypeScript 0.8)
2013 – TypeScript 0.9 发布,支持泛型了
2014 – TypeScript 1.0 发布,Visual Studio 2013 默认支持 TypeScript 了。同时,源码从CodePlex 迁移到 Github
2017 – TypeScript 2.1 发布
2018 – TypeScript 3.2 发布
TypeScript 最初是个微软内部项目,叫 Strada,致力于提升大型 JS 项目(当时内部需求是 Bing Maps、 Office Web Apps 甚至 Windows 8 apps)的可靠性和可维护性。2010 年开始开发,2012 年 10 月发布了第一个开源版本,持续迭代至今。
如果想要了解更多关于TypeScript更详尽的历史,可以访问下面传送门。
【TypeScript的前世今生的传送门】
二、什么是TypeScript?
TypeScript是微软开发的一个开源的编程语言,通过在javascript的基础上添加静态类型定义构建而成。
2012年10月,微软发布了首个公开版本的TypeScript。
2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript。
当前最新正式版本为TypeScript 5.3, 2024年1月发布。
TypeScript 是具有类型语法的 JavaScript,是一门强类型的编程语言。
三、静态类型检查
TypeScript 强调变量类型的声明,可以提前发现类型错误,减少运行时的错误。使用类型注解可以明确标识变量的类型,编译器会在编译时进行类型检查。
let count:number = 100
// 上面声明时强调了count为number类型,但下面又把count赋值为string类型
// 所以下面这行在TypeScript静态类型检查会报红,在JavaScript中是显示正常的
count = '1'
当声明了一个变量为某个数据类型时,再把此变量赋其他数据类型的值
在编译中,静态类型检查会使其报红
但是在运行后,代码还是能如期运行的,也不会报错
这边不建议使用TypeScript语法时,忽略静态类型检查进行编程
这样用TypeScript语法的意义就没有了
编程语言的规范及其重要,这是重中之重!
四、类型注解和类型推导
可以使用类型注解显式声明变量、函数的类型。同时,TypeScript 也会根据上下文进行类型推导,可以根据赋值表达式或者函数返回值自动推断出变量的类型。
// 类型注解
let hey:string = 'tony'
// 类型推导
let hi = 9527
这边给hey加上了:string注解,强调hey是string类型的变量
变量hi没有强调任何变量,直接赋值了number值9527,该变量hi自动推导为number类型
五、可选参数和默认参数
在函数声明时,可以通过使用 ? 来定义可选参数,还可以在函数参数中给定默认值来定义默认参数。
const test = (a: string, b?: number, c: boolean = false) => {
console.log(a)
console.log(b)
console.log(c)
}
test('hey')
// 输出 hey, undefined, false
test('hi', 123)
// 输出 hi, 123, false
test('how', 123, true)
// 输出 how, 123, true
?定义了b为可选参数,这个参数可输入可不输入,不输入时 b = undefined
在定义参数时输入值,如 c:boolean = false,这样参数 c 的默认值就为 false,如果不输入参数,c = false
六、接口和类型别名
可以使用接口(interface)和类型别名(type)来定义自定义类型。接口用于定义对象的结构和属性,类型别名用于为类型定义别名,提高代码可读性。
接口
// 声明一个Person接口
interface Person {
name: string,
age: number
}
// 创建一个类型为接口Person的对象p
const p: Person = {
name: 'Tony',
age: 18
}
接口的可选设置
interface Person {
name: string,
age?: number // 可选参数
}
类型
// 声明一个Person类型
type Person = {
name: string,
age?: number
}
const p: Person = {
name: 'Tony',
}
七、类和继承
TypeScript 支持类和继承,可以使用关键字 class 来定义类,并且可以使用 extends 关键字继承一个类。
接口的继承
一般不继承写接口代码如下:
// 原价商品类型
interface GoodsType {
id: string,
price: number
}
// 打折商品类型
interface DisGoodsType {
id: string,
price: number,
disPrice: number
}
接口的很多属性是可以进行类型复用的,使用 extends 实现接口继承,实现类型复用
以下代码使用继承实现类型复用,代码如下:
// 原价商品类型
interface GoodsType {
id: string,
price: number
}
// 打折商品类型
interface DisGoodsType extends GoodsType{
disPrice: number
}
交叉类型模拟继承
type A = {
propA: string
}
type B = {
propB: number
}
type C = A & B
const obj: C = {
propA: 'hey',
propB: 9527
}
类型别名配合交叉类型(& 与)可以模拟继承,同样可以实现类型复用
八、泛型
TypeScript 提供了泛型(Generics)的支持,可以在类和函数中使用泛型来增加代码的灵活性和重用性。
什么是泛型
泛型(Generics)是指在定义接口、函数等类型的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性, 使用泛型可以复用类型并且让类型更加灵活。
泛型接口
在接口类型的名称后面使用 < T > 即可声明一个泛型参数,接口里的其他成员都能使用该参数的类型。
interface Goods {
id: number,
goodName: string
}
interface User {
name: string,
age: number
}
// 定义泛型
interface ResData<T> {
code: number,
msg: string,
data: T
}
// 定义泛型参数为User
let userData: ResData<User> = {
code: 200,
msg: 'su***ess',
data: {
name: 'Tony',
age: 18
}
}
// 定义泛型参数为Goods
let goodsData: ResData<Goods> = {
code: 200,
msg: 'su***ess',
data: {
id: 1,
goodName: 'iPhone'
}
}
找到可变的类型部分通过泛型抽象为泛型参数(定义参数)
在使用泛型的时候,把具体类型传入到泛型参数位置 (传参)
泛型函数
在函数名称的后面使用 < T > 即可声明一个泛型参数,整个函数中(参数、返回值、函数体)的变量都可以使用该参数的类型
const createArray = <T>(len: number, value: T): T[] => {
let result = []
for (let i = 0; i < len; i++) {
result[i] = value
}
return result
}
createArray<string>(4, '100') // ['100','100','100','100']
createArray<number>(4, 100) // [100,100,100,100]
泛型约束
泛型的特点就是灵活不确定,有些时候泛型函数的内部需要访问一些特定类型的数据才有的属性,此时会有类型错误,需要通过泛型约束解决。
// 定义接口
interface lengthObj {
// 带有长度字段的接口
length: number
}
// 泛型约束
function logLen<T extends lengthObj>(obj: T) {
console.log(obj.length)
}
// 泛型约束(ES6箭头函数写法)
const logLen = <T extends lengthObj>(obj: T) => {
console.log(obj.length)
}
九、枚举
枚举(Enum)是一种方便的数据类型,它用于定义一组具有相同类型的常量,并可以给这些常量命名,方便代码中对它们的引用。
代码示例:
enum EnumName {
value1 = 1,
value2 = 2,
value3 = 3
}
// 打印结果
console.log(`EnumName.value1: ${EnumName.value1}`)
console.log(`EnumName.value2: ${EnumName.value2}`)
console.log(`EnumName.value3: ${EnumName.value3}`)
浏览器控制台打印结果如下:
其中,EnumName 为枚举类型的名称,value1、value2、value3 等为枚举常量的名称,1、2、3 等为枚举常量的值。不指定值时,默认从 0 开始自增。
代码示例:
enum Color {
Red,
Green,
Blue
}
// 打印结果
console.log(`Color.Red: ${Color.Red}`)
console.log(`Color.Green: ${Color.Green}`)
console.log(`Color.Blue: ${Color.Blue}`)
打印结果:
十、快速安装
在Node.js环境下
在控制台输入:
npm install -g typescript
在package.json文件中
会新增一个依赖项如下:
"devDependencies": {
"typescript": "^5.3.3"
}
结语
Mozilla创造了JavaScript,Microsoft创建了TypeScript,Huawei进一步推出了ArkTS
由于我们中国主力研发团队Huawei的支持,在鸿蒙生态中使用ArkTS作为客户端开发语言
对于学习TypeScript这门语言对于ArkTS有着相辅相成的作用
个人还是比较支持我们国产研发团队推出的语言产品架构
毕竟,我们中国的繁荣富强,才能保证整个社会的安定
位卑未敢忘忧国,事定犹须待阖棺。