TypeScript笔记

1. 安装TS

npm i -g typescript

查看是否TS安装成功

tsc
显示图片中内容表示安装成功

2. 编译TS代码

Node.js/浏览器,只认识 JS 代码,不认识 TS 代码。需要先将 TS 代码转化为 JS 代码,然后才能运行

tsc xxx.ts
ts编译js的过程

3. 简化编译TS代码

  • 问题描述:每次修改代码后,都要重复执行两个命令,才能运行 TS 代码,太繁琐。
  • 简化方式:使用 ts-node 包,直接在 Node.js 中执行 TS 代码。
  • 安装命令:npm i -g ts-node(ts-node 包提供了 ts-node 命令)。
  • 使用方式:ts-node hello.ts。
  • 解释:ts-node 命令在内部偷偷的将 TS -> JS,然后,再运行 JS 代码。
ts-node hellos.ts

4. TS的类型

类型 描述 例子
number 任意数字 1,-1,1.11
string 任意字符串 “hi”,'hi',hi
boolean 布尔值 true,false
字面量 限制变量的值就是该字面量的值 其本身
any 任意类型 *
unknown 类型安全的any *
void 没有值或undefined 空值或undefined
never 不能是任何值 没有值
object 任意js对象 { name: '张三' }
array 任意js数组 [1,2,3]
tuple 元素,TS新增类型,固定长度数组 [4,5]
enum 枚举,TS新增类型 enum(A,B)

4.1 字面量类型声明(场景少)

下面这种方式声明的不能修改值

let a:  10
a = 10      // 打印 10
a = 20      // 报
a = '20'    // 报错

使用 | 连接多个类型(联合类型)
let b: 'abc' | '123'
b = 'abc'      // 打印 abc
b = '123'      // 打印 123


let c: boolean | string
c = 'abc'      // 打印 abc
c = true      // 打印 true

4.2 number类型

let a:number = 10
a = 10      // 打印 10
a = 20      // 打印 20
a = '20'    // 报错

4.3 string类型

let a:string = '10'
a = '100'        // 打印 100
a = 'hello'      // 打印 hello
a = 20          // 报错
a = false      // 报错

4.4 boolean类型

let a:boolean = true
a = false      // 打印 false
a = true      // 打印 true
a = 'true'    // 报错

let b:boolean = Boolean(1) // 也可以使用Boolean转译
b      // 打印 true

4.5 any类型(尽量少用)

  • 设置了any,相当于对该变量关闭了TS的类型检测
  • any类型变量,它就可以赋值给任意变量
  • 不设置类型时,默认是any类型
let a:any
let b          // 不设置类型时,默认是any类型
a = 10      // 打印 10
a = true      // 打印 true
a = '20'    // 打印 20

let b:string
b = a   // 不报错,a是any类型,它就可以赋值给任意变量

4.6 unknown类型

  • unknown表示未知类型, 是一个安全的any
  • unknown类型的变量,不能直接赋值给其它变量
let a:unknown
a = 10      // 打印 10
a = true      // 打印 true
a = '20'    // 打印 20

let b:string
a = 'hi'
b = a   // 报错,a的值虽然是字符串,但类型是unknown,所以不能赋值给为string的b

// 如果要把unknown类型的值赋值给其它变量,则可以使用类型断言,有两种方法:
b = a as string      // 可以告诉解析器变量的实际类型
b = <string>a

4.7 void类型(多用于函数)

  • void用来表示空,以函数为例,就表示没有返回值的函数
  • void类型的用法,主要是用在我们不希望调用者关心函数返回值的情况下,比如通常的异步回调函数
  • void是函数没有显式返回任何值(例如consloe.log)时的返回类型
function voidFn(): void {
    console.log('test void')
}
voidFn()

4.8 never类型

  • never是函数根本不返回(例如函数抛出异常,或者永远运行下去)时使用的类型
function neverFn(): never {
    throw new Error('test never')
}
neverFn()

4.9 object类型(几乎不用)

  • object 代表所有非值类型的类型,例如数组、对象、函数等,常用于泛型约束
  • 在js中万物皆对象,所以object几乎很少用
let a:object
a = {}
a = function () {}
  • 在使用{}指定对象中可以包含哪些属性
  • 语法:{属性名:属性类型,属性名:属性类型,属性名?:属性类型}
  • {属性名:属性类型}表示必填参数,不写报错
  • {属性名?:属性类型}表示可选参数
  • [propName:string]:any 表示任意类型的属性
let b:{name:string,age?:number,[propName:string]:any}
b = { name: '张三', age: 20, a: 123, b: 'hi'}

4.10 array类型

语法

  • let xx:类型[]
  • let xx:Array<类型>
let a:string[] 
或
let a:Array<string>
a = ['a', 'b', 'c']

let b:number[]
或
let b:Array<number>
b = [1, 2, 3]

4.11 tuple类型

  • tuple是元组类型,表示固定长度的数组
  • 语法:[类型,类型,类型]
let a:[string,number]
a = ['a', 2]      // 打印 ['a',2]
a = ['a', 2, 3]      // 报错,不能超过元组定义时的元素个数

4.12 enum类型

  • enum表示枚举类型
// 定义性别的枚举对象
enum Gender{
  Male = 0,
  Female = 1
}
let a: { name:string,gender:Gender }
a = {
  name: '张三',
  gender:Gender.Male
}
console.log(a.gender===Gener.Male)    // 打印 true

5. 类型的别名

  • 用于简化类型的定义
let a: 1 | 2 | 3 | 4      // 表示a可以定义的值是1234其中一个
let b: 1 | 2 | 3 | 4
a = 1      // 打印 1
a = 5      // 报错

// 可以简化为
type myNum =  1 | 2 | 3 | 4
let a: myNum
let b: myNum

6. 类(class)

含义:它是用来创建具有相似属性和行为的对象的一个模板或蓝图。类定义了对象的属性(成员变量)和行为(成员函数),并通过创建对象来实例化类。对象是具有类类型的变量

类与对象的关系:
(1)类是对象的抽象,而对象是类的具体实例
(2)类是抽象的,不占用内存,而对象是具体的,占用存储空间
(3)类是用于创建对象的规划,抽象

6.1 创建类

// 语法
class 类名{
  属性:类型
  ...
  constructor(参数1:参数1类型,参数2:参数2类型,...){
    this.属性 = 参数1
    ...
  }
  方法(){
    方法体
  }
  ...
}

例子

class Dog {
    name : string
    age : number

    # 构造函数,会在对象创建时调用
    constructor(name : string, age : number) {
        this.name = name
        this.age = age
    }

    say() {
        console.log('汪汪汪汪');
    }
}

const dog = new Dog('旺财', 3)
console.log(dog);
dog.say()
类的基本用法

6.2 类的继承

基础用法

// 父类
class Animal{
    name: string
    age: number

    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    say() {
        console.log(this.name + '在汪汪叫')
    }
}

// 子类
# 子类使用extends关键字来表示继承父类
class Dog extends Animal{
    # 子类中也可以有自己的属性和方法
    sex: string

    # super表示当前类的父类
    # 构造函数中必在最前面加上super来调用一下父类的属性
    constructor(name: string, age: number, sex: string) {
        super(name, age)
        this.sex = sex
    }

    run() {
        console.log(`一只叫${this.name}${this.age}岁的${this.sex}狗在跑`)
    }

    # 如果子类中也定义了与父类中一样的方法,会覆盖父类中的方法,见图2
    say() {
        console.log('子类重写父类的方法')
    }
}

const dog = new Dog('旺财', 4)
console.log(dog);
dog.say()
dog.run()
图1
图2

6.3 抽象类

  • 以abstract开头的类就是抽象类
  • 抽象类和其它类区别不大,只是不能用来创建对象
  • 抽象类就是专门用来被继承的类
  • 抽象类中可以添加抽象方法
// 父类
abstract class Animal {
    name: string
    age: number

    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    /**
     * 定义抽象方法
     *  1.使用abstract开头,没有方法体
     *  2.抽象方法只能定义在抽象类,子类必须对抽象方法进行重写
     */
    abstract say(): void
}

// 子类
class Dog extends Animal {
    sex: string

    constructor(name: string, age: number, sex: string) {
        super(name, age)
        this.sex = sex
    }

    run() {
        console.log(`一只叫${this.name}${this.age}岁的${this.sex}狗在跑`)
    }
}

// const animal1 = new Animal() // 不能创建对象,会报错
const dog = new Dog('大黄',3,'公')
dog.run()
console.log(dog);

6.4 接口

  • 接口用来定义一个类结构
// 描述一个对象的类型
type myType = {
    name: string
    age: number
}
// 不可重复声明
// type myType={
//     sex:string
// }

/**
 * 接口用来定义一个类结构
 *  1.用来定义一个类中应该包含的属性和方法
 *  2.接口也可以当成类型声明使用
 *  3.可以重复声明,表示追加类的属性和方法
 */
interface myInter {
    name: string
}

interface myInter {
    age: number
}

// 用来规定类型声明,相当于type别名的用法
const obj: myInter = {
    name: 'zs',
    age: 20
}

/**
 * 接口用来定义一个类结构
 *  1.接口可以在定义类的时候用来限制类的结构
 *  2.接口中的所有属性都不能有实际的值
 *  3.接口只定义对象的结构,面不鼒实际值
 *  4.有接口中所有的方法都是抽象方法
 */
interface animalInter {
    name: string

    say(): void
}

/**
 * 定义类时,可以使类去实现一个接口
 * 实现接口就是使类满足接口的需求
 */
class Animal implements animalInter {
    name: string;

    constructor(name: string) {
        this.name = name
    }

    say(): void {
        console.log('叫叫叫')
    }

}

const dog = new Animal('小黑')
console.log(dog);
dog.say();
image.png

6.5 属性的修饰符

修饰符的作用是为了数据更加安全

修饰符 自身内部 子类内部 实例对象
static 可以访问 可以访问 不能访问
public 可以访问 可以访问 可以访问
private 可以访问 不能访问 不能访问
protected 可以访问 可以访问 不能访问
  • static:静态属性,修饰的属性只能通过类访问,实例对象不能访问
  • public:公有属性,修饰的属性可以在任意位置访问和修改,属性默认就是public
  • private:私有属性,只能在类内部进行访问和修改
  • protected:受保护的属性,只能在当着类和当前子类中使用
// 属性的修饰符
class A {
    _name : string
    private _age : number
    protected _sex : string
    static _height : number = 180

    constructor(name : string, age : number, sex : string) {
        this._name = name
        this._age = age
        this._sex = sex
    }

    get age() {
        return this._age
    }

    set age(value : number) {
        if (value >= 0) {
            this._age = value
        }
    }
}

const a = new A('ZS', 18, '男')
console.log(a);
console.log(a._name);       // ZS
// console.log(a._age);  // 不能访问

// 使用了get age,就可以使用a.age,直接访问
console.log(a.age);  // 18
// 使用了set age,就可以使用a.age=xxx  正常赋值
a.age = 50
// console.log(a._sex)  // 不能访问
console.log(a.age)  // 50
// console.log(a._height)  // 不能访问
console.log(A._height)  // 180
image.png

6.6 类的属性的简写

class A{
    constructor(public name:string,public age:number) {
    }
}

const a = new A('zs',30)
console.log(a)
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容