TypeScript快速入门

一、TypeScript 简介

1. TypeScript 由微软开发,是基于 JavaScript 的⼀个扩展语⾔。

2. TypeScript 包含了 JavaScript 的所有内容,即: TypeScript 是JavaScript 的超集。

3. TypeScript 增加了:静态类型检查、接⼝、 泛型等很多现代开发特性,更适合⼤型项⽬的开发。

4. TypeScript 需要编译为 JavaScript ,然后交给浏览器或其他 JavaScript 运⾏环境执⾏。

二、为何需要 TypeScript

今⾮昔⽐的 JavaScript:

  • JavaScript 当年诞⽣时的定位是浏览器脚本语⾔,⽤于在⽹⻚中嵌⼊简单的逻辑,且代码量很少。
  • 随着时间的推移,JavaScript 变得越来越流⾏,如今的 JavaScript 已经可以全栈编程了。
  • 现如今的 JavaScript 应⽤场景⽐当年丰富的多,代码量也⽐当年⼤很多,随便⼀个 JavaScript 项⽬的代码量,可以轻松的达到⼏万⾏,甚⾄⼗⼏万⾏!
  • 然⽽ JavaScript 当年“ 出⽣简陋” ,没考虑到如今的应⽤场景和代码量,逐渐就出现了很多困扰。

JavaScript 中的困扰:

  • 不清楚的数据类型
let welcome = 'hello'
welcome() // 此⾏报错:TypeError: welcome is not a function
  • 有漏洞的逻辑

  • 访问不存在的属性

  • 低级的拼写错误

静态类型检查:

在代码运⾏前进⾏检查,发现代码的错误或不合理之处,减⼩运⾏时出现异常的⼏率,此种检查叫『静态类型检查』,TypeScript 和核⼼就是『静态类型检查』,简⾔之就是把运⾏时的错误前置

同样的功能,TypeScript 的代码量要大于 JavaScript,但由于 TypeScript 的代码结构更加清晰,在后期代码的维护中 TypeScript 却胜于 JavaScript。

三、编译 TypeScript

浏览器不能直接运行TypeScript 代码,需要编译为 JavaScript 再交由浏览器解析器执⾏。

1. 命令⾏编译

要把 .ts ⽂件编译为 .js ⽂件,需要配置 TypeScript 的编译环境,步骤如下:

第⼀步:创建⼀个 demo.ts ⽂件,例如:

第⼆步:全局安装 TypeScript(带有指令的包,安装后才会有tsc编译命令)

npm i typescript -g

第三步:使用命令编译 .ts ⽂件

tsc demo.ts  

2. 自动化编译

第⼀步:创建 TypeScript 的编译控制⽂件(tsconfig.json)

tsc --init
  1. 工程中会⽣成⼀个 tsconfig.json 配置⽂件,其中包含着很多编译时的配置。
  2. 观察发现,默认编译的 JS 版本是 ES7 ,我们可以⼿动调整为其他版本。

第⼆步:监视⽬录中的 .ts ⽂件变化,.ts文件变化会实时编译成.js

tsc --watch  
或
tsc -w

第三步:小优化,当编译出错时不生成 .js ⽂件,可以修改 tsconfig.json 中的 noEmitOnError 配置实现

四、类型声明

使⽤ : 来对变量、函数形参、函数的返回值,进行类型声明(冒号后面可以带个空格,当然不带也行):

在 : 后也可以写字⾯量类型,不过实际开发中⽤的不多。

五、类型推断

TS 会根据我们的代码,进行类型推导,例如下⾯代码中的变量 d ,只能存储数字

但要注意,类型推断不是万能的,⾯对复杂类型时推断容易出问题,所以尽量还是明确的编写类型声明!

六、数据类型总览!!!

JavaScript 中的数据类型:

TypeScript 中的数据类型:

注意点:在 JavaScript 中的这些内置构造函数:Number、String、Boolean ,用于创建基本数据类型对应的包装对象,在日常开发时很少使用,在 TypeScript 中也是同理,所以在 TypeScript 中进行类型声明时,通常都是用小写的 number、string、boolean。

例如下⾯代码:

七、常用数据类型与语法

1. any类型

any 的含义是:任意类型,⼀旦将变量类型限制为any,那就意味着放弃了对该变量的类型检查。它可以是任意类型。

注意点: any 类型的变量,可以赋值给任意类型的变量

2. unknown类型

unknown 的含义是:未知类型,适⽤于声明起初不确定数据的具体类型是什么,要后期才能确定

1. unknown 可以理解为⼀个类型安全的 any 。

2. unknown 会强制开发者在使用之前进行类型检查,从而提供更强的类型安全性。

3. 读取 any 类型数据的任何属性都不会报错,⽽ unknown 正好与之相反。

3. never类型

never 的含义是:任何值都不是,即:不能有值,例如undefined、nul、0 都不行!

1.几乎不用 never 去直接限制变量,因为没有意义,例如:

2. never ⼀般是 TypeScript 主动推断出来的,例如:

3. never 也可⽤于限制函数的返回值类型,也就是函数不能有任何的返回值。

4. void类型

void 的含义是空,即:函数没有返回值,调用者也不应依赖其返回值进行任何操作

1. void 通常⽤于函数的返回值类型声明

2. 以下写法均符合规范

3. 那限制函数返回值时,是不是 undefined 和 void 就没区别呢?    有区别。因为还有这句话:【返回值类型为 void 的函数,调用者不应依赖其返回值进行任何操作,而undefined可以依赖其返回值进行操作!】对比下面两段代码:

理解 void 与 undefined:

  • void 是⼀个广泛的概念,⽤来表达“ 空” ,而 undefined 则是这种“ 空” 的具体 实现。
  • 因此可以说 undefined 是 void 能接受的⼀种“ 空” 的状态。
  • 也可以理解为: void 包含 undefined ,但 void 所表达的语义超越了 undefined , void 是⼀种意图上的约定,⽽不仅仅是特定值的限制。

总结:

如果⼀个函数返回类型为 void ,那么:

1. 从语法上讲:函数是可以返回 undefined 的,⾄于显式返回,还是隐式返回,这⽆所谓!

2. 从语义上讲:函数调用者不应关心函数的返回值,也不应依赖返回值进行任何操作! 即使我们知道它返回了 undefined 。

5. object类型

关于 object 与 Object ,直接说结论:实际开发中用的相对较少,因为范围太⼤了。

object(小写)

object (小写)的含义是:所有的非原始类型,可存储:对象、函数、数组等,由于限制的范围⽐较宽泛,在实际开发中使⽤的相对较少。

Object(大写)

  • 官⽅描述:所有可以调⽤ Object ⽅法的类型。
  • 简单记忆:除了 undefined 和 null 的任何值。
  • 由于限制的范围实在太⼤了!所以实际开发中使⽤频率极低。

如何声明对象类型

1. 实际开发中,声明一般对象类型,通常使用以下形式:

2. 索引签名:定义对象可以具有任意数量的属性,这些属性的键和类型是可变的, 常用于:描述类型不确定的属性,(具有动态属性的对象)。

语义:键的类型是什么,值的类型是什么

如何声明函数类型

下面代码中,count变量已经被声明成此种函数类型了,以前后只能赋值符合此种形式的函数给它

//小括号是定义函数的形参表,=> 用于分个形参表和函数的返回值类型
let count: (a: number, b: number) => number

count = function(x,y){
    return x+y
}

备注:

TypeScript 中的 => 是用于定义变量为函数类型的语法,表示函数的返回值类型,描述其参数类型和返回类型。


JavaScript 中的 =>是一种定义函数的语法,是具体的函数实现。

函数类型声明还可以使用:接口、自定义类型等方式,下文中会详细讲解

声明数组类型

备注:上述代码中的 Array 属于泛型,下⽂会详细讲解。

6. tuple类型

元组 (Tuple) 是⼀种特殊的数组类型,可以存储固定数量的元素,并且每个元素的数据类型已知且可以不同。元组⽤于精确描述一组值的类型, ? 表示可选元素

7. enum类型

枚举( enum )用于定义⼀组命名常量,它能增强代码的可读性,也让代码更好维护。

如下代码的功能是:根据调用 walk 函数时传入不同的参数,执行不同的逻辑,存在的问题是调⽤ walk 时传参时没有任何提示,编码者很容易写错字符串内容;并且用于判断逻辑的 up 、down、 left 、 right 是连续且相关的⼀组值,那此时就特别适合使用枚举。

1. 数字枚举

数字枚举⼀种最常见的枚举类型,其成员的值会自动递增,且数字枚举还具备反向映射的特点,在下面代码的打印中,不难发现:可以通过来获取对应的枚举成员名称

  • 在控制台打印Direction枚举,可以看到它其实就是一个对象。

也可以指定枚举成员的初始值其后的成员值会自动递增。

使用数字枚举完成刚才 walk 函数中的逻辑,此时我们发现: 代码更加直观易读,⽽且类型安全,同时也更易于维护。

2. 字符串枚举

枚举成员的值是字符串, 需要初始化,并不具备反向映射的特点

3. 常量枚举

管方描述:常量枚举是⼀种特殊枚举类型,它使⽤const关键字定义,在编译时会被内联,避免生成⼀些额外的代码。

何为编译时内联?

所谓“ 内联” 其实就是 TypeScript 在编译时,会将枚举成员引⽤替换为它们的实际值, ⽽不是⽣成额外的枚举对象。这可以减少⽣成的 JavaScript 代码量,并提高运行时性能。

使⽤普通枚举的 TypeScript 代码如下:

编译后⽣成的 JavaScript 代码量较⼤ :

使⽤常量枚举的 TypeScript 代码如下:

编译后⽣成的 JavaScript 代码量较⼩:

8. type关键词

type关键字,可以为任意的数据类型创建别名,让代码更简洁、可读性更强,同时能更方便地进行类型复用和扩展。

1. 基本用法

数据类型的别名使用type关键字定义,type 后跟类型名称,例如下面代码中 num 是类型别名:

2. 定义联合类型

联合类型是⼀种高级类型,它表示一个值可以是几种不同的类型之一

3.交叉类型

交叉类型(Intersection Types)允许将多个类型合并为⼀个类型。合并后的类型将拥有所有被合并类型的成员。交叉类型通常用于定义对象类型

9. ⼀个特殊情况

先来观察如下两段代码:

代码段1(正常)

在函数定义时,声明函数的返回值类型为void,那么函数的返回值就必须是空。

代码段2(特殊)

使⽤类型声明限制函数返回值为 void 时, TypeScript 并不会严格要求函数返回空。

为什么会这样?

是为了确保如下代码成立,我们知道 Array.prototype.push 的返回值是⼀个数字, ⽽ Array.prototype.forEach ⽅法期望其回调的返回类型是 void 。

10. 复习类相关知识

本小节是复习类相关知识,如果有相关基础可以跳过。

11. 属性修饰符

可以用于修饰类的属性和成员方法,如果不写,默认为public修饰:

public 修饰符:

属性的简写形式:

protected 修饰符:

private 修饰符:

readonly 修饰符:

12. 抽象类

概述:抽象类是一种无法被实例化的类,专门用来定义类的结构和行为,类中可以写抽象方法,也可以写具体实现抽象类主要用来为其派生类提供一个基础结构,要求其派生类必须实现其中的抽象方法。


简记:抽象类不能实例化,其意义是可以被继承,抽象类里可以有普通方法、也可以有抽象方法。

通过以下场景,理解抽象类:
我们定义一个抽象类 Package ,表示所有包裹的基本结构,任何包裹都有重量属性 weight ,包裹都需要计算运费。但不同类型的包裹(如:标准速度、特快专递)都有不同的运费计算方式,因此用于计算运费的 calculate 方法是一个抽象方法,必须由具体的子类来实现。

StandardPackage 类继承了 Package ,实现了 calculate ⽅法:

ExpressPackage 类继承了 Package ,实现了 calculate ⽅法:

13. interface(接口)

interface 是⼀种定义结构的方式,主要作用是为:类、对象、函数等定义⼀种契约,这样可以确保代码的⼀致性和类型安全,但要注意 interface 只能定义格式,不能包含任何实现

定义类的结构

定义对象类型的结构

规定了对象需要有哪些属性和哪些方法

定义函数的结构

接⼝之间的继承

⼀个 interface 继承另⼀个 interface ,从⽽实现代码的复⽤

接⼝的⾃动合并(可重复定义)

总结:何时使⽤接口?

1.定义对象的格式: 描述数据模型、API 响应格式、配置对象.…等等,是开发中用的最多的场景。
2.类的契约:规定一个类需要实现哪些属性和方法。
3.扩展已有接口:一般用于扩展第三方库的类型,这种特性在大型项目中可能会用到,

14. ⼀些相似概念的区别

14.1. interface 与 type 的区别

相同点: interface 和 type 都可以定义对象结构,在定义对象结构时两者可以互换。

不同点:

  • interface :更专注于定义对象和类的结构,支持继承、合并。
  • type :可以定义类型别名、联合类型、交叉类型,但不⽀持继承和自动合并。

14.2. interface 与 抽象类的区别

相同点:都能定义⼀个类的格式(定义类应遵循的契约)

不相同:

  • 接⼝:只能描述结构,不能有任何实现代码,⼀个类可以实现多个接口。
  • 抽象类:既可以包含抽象⽅法,也可以包含具体⽅法, ⼀个类只能继承⼀个抽象类。

八、泛型

泛型允许我们在定义函数、类或接口时,使用类型参数来表示未指定的类型,这些类型参数在具体使用时,才会被指定具体的类型,泛型能让同⼀段代码适⽤于多种类型,同时仍然保持类型的安全性。

举例:如下代码中 <T>就是泛型,(不⼀定非叫 T ),设置泛型后即可在函数中使用 T 来当作数据类型使用

九、类型声明⽂件

类型声明文件是 TypeScript 中的⼀种特殊⽂件,通常以 .d.ts 作为扩展名。它的主要作用是为现有的 JavaScript 代码提供类型信息,使得 TypeScript 能够在使用这些 JavaScript 库或模块时进行类型检查和提示

TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集,添加了静态类型和其他特性以便于构建大型应用。下面是一个 TypeScript 快速入门指南: ### 基础概念 #### 1. **安装** 首先需要安装 Node.js 和 npm(Node 包管理工具)。接着通过以下命令全局安装 TypeScript 编译器: ```bash npm install -g typescript ``` 可以运行 `tsc --version` 来检查是否成功安装。 #### 2. **基础语法** ##### a) 类型声明 TypeScript 引入了静态类型的特性,这有助于捕获潜在错误并提供更好的 IDE 支持。 ```typescript let num: number = 10; let str: string = "Hello"; let bool: boolean = true; // 数组类型 let arr: number[] = [1, 2, 3]; let arrStr: Array<string> = ["a", "b", "c"]; // 元组 Tuple (固定长度和类型的数组) let tuple: [string, number] = ['hello', 5]; // 枚举 Enum enum Color { Red, Green, Blue }; let c: Color = Color.Green; console.log(c); // 输出结果为 1 ``` ##### b) 函数 函数支持输入参数和返回值类型的指定。 ```typescript function add(x: number, y: number): number { return x + y; } const result = add(4, 6); console.log(result); // 结果为 10 ``` ##### c) 接口 Interface 接口用于描述对象的结构,包括属性及其对应的类型。 ```typescript interface Person { name: string, age?: number, // 可选字段用 ? } function printPerson(person: Person): void { console.log(`Name: ${person.name}, Age: ${person.age}`); } printPerson({name: 'Alice'}); ``` #### 3. **高级功能** ##### d) 泛型 Generics 泛型允许我们创建更通用、可复用组件。 ```typescript function identity<T>(arg: T): T { return arg; } let output = identity<string>("myString"); ``` ##### e) 联合类型 Union Types 联合类型表示某个变量可能是几种类型之一。 ```typescript let value: string | number; // 表示value既可以是字符串也可以是数字 value = "test"; // 正确赋值 value = 123; // 同样正确 ``` ##### f) 类 Class & 继承 Inheritance ```typescript class Animal { move(distanceInMeters: number = 0){ console.log('Animal moved '+ distanceInMeters +'m.'); } } class Dog extends Animal{ bark(){ console.log("Woof! Woof!"); } } const doggy = new Dog(); doggy.bark(); // 输出:"Woof! Woof!" doggy.move(10); // 输出:"Animal moved 10m." ``` --- 以上只是对 TypeScript 的简短介绍,更多深入内容还需进一步学习研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值