快速上手

  1. //全局安装
  2. npm install -g typescript
  1. //查看版本
  2. tsc -v

一个例子

  1. //hello.ts
  2. function sayHello(person: string) {
  3. return 'Hello, ' + person;
  4. }
  5. let user = 'Tom';
  6. console.log(sayHello(user));

执行

  1. tsc hello.ts

vscode中自动编译

  1. tsc --init

终端 - 运行任务
image.png
注:如果出现报错,需要配置默认终端为powerShell。配置完成之后一定要关闭 vscode 在重新打开
image.png

使用webpack打包TS

  1. npm install -D typescript
  2. npm install -D webpack@4.41.5 webpack-cli@3.3.10 webpack-dev-server@3.10.2
  3. npm install -D html-webpack-plugin clean-webpack-plugin ts-loader cross-env
  4. //为防止错误
  5. "devDependencies": {
  6. "clean-webpack-plugin": "3.0.0",
  7. "cross-env": "^7.0.3",
  8. "html-webpack-plugin": "^4.5.0",
  9. "ts-loader": "^8.0.11",
  10. "typescript": "^4.4.2",
  11. "webpack": "^4.41.5",
  12. "webpack-cli": "^3.3.10",
  13. "webpack-dev-server": "^3.10.2"
  14. }

基本语法

基础类型

布尔值

  1. let isDone: boolean = false;
  2. isDone = true;
  3. // isDone = 2 // error

数字

  1. let a1: number = 10 // 十进制

字符串

  1. let name:string = 'tom'
  2. name = 'jack'
  3. // name = 12 // error
  4. let age:number = 12
  5. const info = `My name is ${name}, I am ${age} years old!`

undefined 和 null

  1. let u: undefined = undefined
  2. let n: null = null

数组

  1. //方式一
  2. let list1: number[] = [1, 2, 3]
  3. //方式二 Array<元素类型>
  4. let list2: Array<number> = [1, 2, 3]

元祖(Tuple)
元祖类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同

  1. let t1: [string, number]
  2. t1 = ['hello', 10] // OK
  3. t1 = [10, 'hello'] // Error
  1. console.log(t1[0].substring(1)) // OK
  2. console.log(t1[1].substring(1)) // Error, 'number' 不存在 'substring' 方法

枚举
enum类型是对javascript标准数据类型的一个补充,使用枚举类型可以为一组数值赋予友好的名字

  1. enum Color {
  2. Red,
  3. Green,
  4. Blue
  5. }
  6. // 枚举数值默认从0开始依次递增
  7. // 根据特定的名称得到对应的枚举数值
  8. let myColor: Color = Color.Green // 0
  9. console.log(myColor, Color.Red, Color.Blue)

any
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any 类型来标记这些变量:

  1. let notSure: any = 4
  2. notSure = 'maybe a string'
  3. notSure = false // 也可以是个 boolean

在对现有代码进行改写的时候,any 类型是十分有用的,它允许你在编译时可选择地包含或移除类型检查。并且当你只知道一部分数据的类型时,any 类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:

  1. let list: any[] = [1, true, 'free']
  2. list[1] = 100

void
某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:

  1. /* 表示没有任何类型, 一般用来说明函数的返回值不能是undefinednull之外的值 */
  2. function fn(): void {
  3. console.log('fn()')
  4. // return undefined
  5. // return null
  6. // return 1 // error
  7. }

声明一个 void 类型的变量没有什么大用,因为你只能为它赋予 undefined 和 null:

  1. let unusable: void = undefined

object
object 表示非原始类型,也就是除 number,string,boolean之外的类型。
使用 object 类型,就可以更好的表示像 Object.create 这样的 API。例如:

  1. function fn2(obj:object):object {
  2. console.log('fn2()', obj)
  3. return {}
  4. // return undefined
  5. // return null
  6. }
  7. console.log(fn2(new String('abc')))
  8. // console.log(fn2('abc') // error
  9. console.log(fn2(String))

联合类型
联合类型(Union Types)表示取值可以为多种类型中的一种
需求1: 定义一个一个函数得到一个数字或字符串值的字符串形式值

  1. function toString2(x: number | string) : string {
  2. return x.toString()
  3. }

需求2: 定义一个一个函数得到一个数字或字符串值的长度

  1. function getLength(x: number | string) {
  2. // return x.length // error
  3. if (x.length) { // error
  4. return x.length
  5. } else {
  6. return x.toString().length
  7. }
  8. }

类型断言
通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript 会假设你,程序员,已经进行了必须的检查。
类型断言有两种形式。 其一是“尖括号”语法, 另一个为 as 语法

  1. /*
  2. 类型断言(Type Assertion): 可以用来手动指定一个值的类型
  3. 语法:
  4. 方式一: <类型>值
  5. 方式二: as 类型 tsx中只能用这种方式
  6. */
  7. /* 需求: 定义一个函数得到一个字符串或者数值数据的长度 */
  8. function getLength(x: number | string) {
  9. if ((<string>x).length) {
  10. return (x as string).length
  11. } else {
  12. return x.toString().length
  13. }
  14. }
  15. console.log(getLength('abcd'), getLength(1234))

类型推断
类型推断: TS会在没有明确的指定类型的时候推测出一个类型
有下面2种情况: 1. 定义变量时赋值了, 推断为对应的类型. 2. 定义变量时没有赋值, 推断为any类型

  1. /* 定义变量时赋值了, 推断为对应的类型 */
  2. let b9 = 123 // number
  3. // b9 = 'abc' // error
  4. /* 定义变量时没有赋值, 推断为any类型 */
  5. let b10 // any类型
  6. b10 = 123
  7. b10 = 'abc'

接口

TypeScript 的核心原则之一是对值所具有的结构进行类型检查。我们使用接口(Interfaces)来定义对象的类型。接口是对象的状态(属性)和行为(方法)的抽象(描述)

  1. /*
  2. TypeScript 中,我们使用接口(Interfaces)来定义对象的类型
  3. 接口: 是对象的状态(属性)和行为(方法)的抽象(描述)
  4. 接口类型的对象
  5. 多了或者少了属性是不允许的
  6. 可选属性: ?
  7. 只读属性: readonly
  8. */
  9. /*
  10. 需求: 创建人的对象, 需要对人的属性进行一定的约束
  11. idnumber类型, 必须有, 只读的
  12. namestring类型, 必须有
  13. agenumber类型, 必须有
  14. sexstring类型, 可以没有
  15. */
  16. // 定义人的接口
  17. interface IPerson {
  18. id: number
  19. name: string
  20. age: number
  21. sex: string
  22. }
  23. const person1: IPerson = {
  24. readonly id: 1,
  25. name: 'tom',
  26. age: 20,
  27. sex?: '男'
  28. }

readonly vs cosnt
最简单判断该用 readonly 还是 const 的方法是要看要把它作为变量使用还是作为一个属性,作为变量使用的话用const,若作为属性则使用 readonly

对于传统的 JavaScript 程序我们会使用函数和基于原型的继承来创建可重用的组件,从ES6开始, JavaScript 程序员将能够使用基于类的面向对象的方式

基本示例

  1. /*
  2. 类的基本定义与使用
  3. */
  4. class Greeter {
  5. // 声明属性
  6. message: string
  7. // 构造方法
  8. constructor (message: string) {
  9. this.message = message
  10. }
  11. // 一般方法
  12. greet (): string {
  13. return 'Hello ' + this.message
  14. }
  15. }
  16. // 创建类的实例
  17. const greeter = new Greeter('world')
  18. // 调用实例的方法
  19. console.log(greeter.greet())

继承
在 TypeScript 里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类。

  1. /*
  2. 类的继承
  3. */
  4. class Animal {
  5. run (distance: number) {
  6. console.log(`Animal run ${distance}m`)
  7. }
  8. }
  9. class Dog extends Animal {
  10. cry () {
  11. console.log('wang! wang!')
  12. }
  13. }
  14. const dog = new Dog()
  15. dog.cry()
  16. dog.run(100) // 可以调用从父中继承得到的方法

公共,私有与受保护的修饰符
默认为 public ,在TypeScript 里,成员都默认为public
private ,它就不能在声明它的类的外部访问
protected , 它的成员在派生类中仍然可以访问

readonly修饰符
readonly , 将属性设置为只读的,只读属性必须在声明时或构造函数里被初始化

  1. class Person {
  2. readonly name: string = 'abc'
  3. constructor(name: string) {
  4. this.name = name
  5. }
  6. }
  7. let john = new Person('John')
  8. // john.name = 'peter' // error

存取器
TypeScript 支持通过 getters/setters 来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

  1. class Person {
  2. firstName: string = 'A'
  3. lastName: string = 'B'
  4. get fullName () {
  5. return this.firstName + '-' + this.lastName
  6. }
  7. set fullName (value) {
  8. const names = value.split('-')
  9. this.firstName = names[0]
  10. this.lastName = names[1]
  11. }
  12. }
  13. const p = new Person()
  14. console.log(p.fullName)
  15. p.firstName = 'C'
  16. p.lastName = 'D'
  17. console.log(p.fullName)
  18. p.fullName = 'E-F'
  19. console.log(p.firstName, p.lastName)

静态属性
我们也可以创建类的静态成员,这些属性存在于类本身上面而不是类的实例上。

  1. /*
  2. 静态属性, 是类对象的属性
  3. 非静态属性, 是类的实例对象的属性
  4. */
  5. class Person {
  6. name1: string = 'A'
  7. static name2: string = 'B'
  8. }
  9. console.log(Person.name2)
  10. console.log(new Person().name1)

抽象类
抽象类做为其它派生类的基类使用。 它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节。 abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。

  1. /*
  2. 抽象类
  3. 不能创建实例对象, 只有实现类才能创建实例
  4. 可以包含未实现的抽象方法
  5. */
  6. abstract class Animal {
  7. abstract cry ()
  8. run () {
  9. console.log('run()')
  10. }
  11. }
  12. class Dog extends Animal {
  13. cry () {
  14. console.log(' Dog cry()')
  15. }
  16. }
  17. const dog = new Dog()
  18. dog.cry()
  19. dog.run()


观看记录
https://www.bilibili.com/video/BV1CK411u75G?p=29&spm_id_from=pageDriver

文档地址
https://24kcs.github.io/vue3_study/chapter2/1_type.html#%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80