Liang2uv's blog Liang2uv's blog
首页
  • 前端文章

    • JavaScript
    • Vue
    • 面试总结
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 小程序笔记
    • TypeScript笔记
    • 数据结构笔记
    • mongoDB笔记
    • nginx笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • 关于
  • 作品集

Liang2uv

我也想成为前端大佬
首页
  • 前端文章

    • JavaScript
    • Vue
    • 面试总结
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 小程序笔记
    • TypeScript笔记
    • 数据结构笔记
    • mongoDB笔记
    • nginx笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • 关于
  • 作品集
  • JavaScript文章

  • Vue文章

  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 小程序笔记
    • TypeScript笔记
      • 基础
        • 什么是typescript
        • 基本数据类型
        • 联合类型
      • 进阶
        • 函数
        • 类
        • 接口
        • 泛型
        • 模块
        • 命名空间
        • 装饰器
    • 数据结构笔记
    • mongoDB笔记
    • nginx笔记
  • 面试总结
  • 前端
  • 学习笔记
Liang2uv
2020-11-04

TypeScript笔记

# typescript笔记

# 基础

# 什么是typescript

typescript是javascript的超集

# 安装

  • 安装命令
npm install -g typescript
1
  • 编译
tsc hello.ts
1

# 基本数据类型

布尔值、数值、字符串、null、undefined、Symbol、Object

  • 布尔值

    let b: boolean = false
    
    1
  • 数值:

    let hex: number = 0xf00d	// 十六进制
    let binary: number = 0b1010	// 二进制
    let octal: number = 0o744	// 八进制
    
    1
    2
    3
  • 字符串

    let str: string = 'Tom'
    
    1
  • null

    let n: null = null
    
    1
  • undefined

    let u: undefined = undefined
    
    1

# 任意值

  • typecript有严格的类型判断,如果everything is any, 就和js差不多

  • 使用任意值

    // 以下编译不会出错
    let anything: any = 'Tom'
    any = 7
    // 如果变量在声明的时候没有指定其类型,将会被自动识别为任意值
    let something
    
    1
    2
    3
    4
    5
  • 如果在定义变量的时候没有声明类型和赋值,则这个变量自动推论为any类型

    let anything
    anything = 1
    anything = 'Tom'
    
    1
    2
    3

# 联合类型

  • 联合类型表示取值可以有多种类型

    let foo: string | number
    
    1
  • 注意:访问联合类型的属性和方法的时候,只能访问这些类型的共有属性和方法

# 进阶

# 函数

# 基础

  • 定义方法:函数声明法、匿名函数法

    // 函数声明法
    function run ():string {
        return 'run'
    }
    // 匿名函数法
    var run2 = function ():string {
        return 'run'
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
  • 传参

    function getInfo (name:string, age: number):string {
        // 打印:小明---13
        return `${name}---${number}`
    }
    // 调用
    getInfo('小明', 13)
    
    1
    2
    3
    4
    5
    6
  • 没有返回值

    function run ():void {}
    
    1
  • 可选参数

    function getInfo (name:string, age?: number):string {
        // 打印:小明---undefined
        return `${name}---${number}`
    }
    // 调用
    getInfo('小明')
    
    1
    2
    3
    4
    5
    6
  • 默认参数

    function getInfo (name:string, age: number = 20):string {
        // 打印:小明---20
        return `${name}---${number}`
    }
    // 调用
    getInfo('小明')
    
    1
    2
    3
    4
    5
    6
  • 剩余参数

    // 写法一
    function sum (...result:number[]):number {
        // 打印:4
        return result.reduce((pre, cur) => pre + cur, 0)
    }
    // 调用
    sum(1, 1, 1, 1)
    
    // 写法二
    function sum (a: number, ...result:number[]):number {
        // 打印:4
        return result.reduce((pre, cur) => pre + cur, a)
    }
    // 调用
    sum(1, 1, 1, 1)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

# 函数重载

function getInfo (name: string):string;
function getInfo (age: number):string;
function getInfo (str: any):any {
    if (typeof str === 'string') {
        return '我叫:' + str
    } else {
        return '我的年龄是:' + str
    }
}
// 调用
getInfo('小明')
getInfo(13)
1
2
3
4
5
6
7
8
9
10
11
12

# 类

# 定义

class Person {
    name: string;
    constructor (name: string) {
        this.name = name
    }
    run ():void {
        console.log(this.name)
    }
    getName ():string {
        return this.name
    }
    setName (name: string):void {
        this.name = name
    }
}
// 使用
var p = new Person ('小明')
p.run()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# getter和setter

  • getter
class Person {
    // es: 这样定义构造器等同于:constructor(name: string) { this._name = _name }
    constructor(private _name: string) {}
    
    get name() {
        return this._name
    }
}
const person = new Person('dell')
// 打印:dell
console.log(person.name)

1
2
3
4
5
6
7
8
9
10
11
12
  • setter
class Person {
    // es: 这样定义构造器等同于:constructor(name: string) { this._name = _name }
    constructor(private _name: string) {}
    
    get name() {
        return this._name
    }
    
    set name(name: string) {
        this._name = name
    }
}
const person = new Person('dell')
// 打印:dell
console.log(person.name)
person.name = 'hello dell'
// 打印:hello dell
console.log(person.name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 继承

class Person {
    name: string;
    constructor (name: string) {
        this.name = name
    }
    run ():void {
        console.log(this.name)
    }
}
class Web extends Person {
    constructor (name: string) {
        // 初始化父类构造函数
        super(name)
    }
    work () {
        console.log(`${this.name}在工作`)
    }
}
var w = new Web('小明')
// 打印:小明
w.run()
// 打印:小明在工作
w.work()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 类里的修饰符

  • 三种修饰符

    • public :类里面、子类、类外面都可以访问
    • protected:类里面、子类可以访问
    • private:在类里面可以访
  • 注:属性不加修饰符,默认是public

  • 示例:

    // public
    class Person {
        public name: string;
        constructor (name: string) {
            this.name = name
        }
        run ():void {
            console.log(this.name)
        }
    }
    class Web extends Person {
        constructor (name: string) {
            // 初始化父类构造函数
            super(name)
        }
        work () {
            console.log(`${this.name}在工作`)
        }
    }
    var w = new Web('小明')
    var p = new Web('大明')
    // 打印:大明
    console.log(p.name)
    // 打印:小明
    w.run()
    // 打印:小明在工作
    w.work()
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

# 静态属性和静态方法

class Person {
    // 实例属性
    public name: string;
    // 静态属性
    static sex = '男'
    constructor (name: string) {
        this.name = name
    }
    // 实例方法
    run ():void {
        console.log(this.name)
    }
    // 静态方法
    static print ():void {
        console.log(Person.sex)
    }
}
// 调用实例方法,打印:小明
var p = new Person('小明')
p.run()
// 调用实例方法,打印:男
Person.print()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 多态

  • 定义:父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现

  • 示例:

      class Animal {
          name: string;
          constructor (name: stirng) {
              this.name = name
          }
          // 具体吃什么不知道,需要继承它的子类去实现
          eat () {
              console.log('吃')
          }
      }
        class Dog extends Animal {
          constructor (name: string) {
              super(name)
          }
          // 实现吃的方法
          eat () {
              return this.name + '吃狗粮'
          }
        }
        class Cat {
          constructor (name: string) {
              super(name)
          }
          // 实现吃的方法
          eat () {
              return this.name + '吃猫粮'
          }
        }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

# 抽象类

  • 定义:它是提供其他类继承的基类,不能直接被实例化,抽象类中的抽象方法不包含具体的实现并且必须在派生类中实现

  • 示例:

    abstract class Animal {
        public name:string;
        constructor(name: string) {
            this.name = name
        }
        abstract eat (): any;
    }
    // 错误写法,抽象类不能被实例化
    // var a = new Animal()
    
    class Dog extends Animal {
        constructor(name: string) {
            super(name)
        }
        // 必须实现抽象类的抽象方法,不实现会报错
        eat () {
            console.log(this.name + '吃狗粮')
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

# 使用ts实现单例设计模式

class Person {
    private static instance: Person;
    static getInstance() {
        if (!this.instance) {
            this.instance = new Person();
        }
        return this.instance;
    }
}
const p1 = Person.getInstance();
const p2 = Person.getInstance();
console.log(p1 === p2)
1
2
3
4
5
6
7
8
9
10
11
12

# 接口

  • 概念:接口是对行为的抽象,具体的行动需要由类去实现

  • 示例:

    // 1. --------对传入的json参数进行约束-------------
    function getUserInfo(userInfo: { name: string, age: number }): void {
        console.log(userInfo)
    }
    // 使用
    getUserInfo({ name: '小明', age: 12 })
    
    // 2. ---------对传入的对象进行约束----------------
    interface UserInfo {
        name: string;	// 注意:分号结束
        age: number;
    }
    function getUserInfo (userInfo: UserInfo) {
        console.log(userInfo)
    }
    // 使用
    var obj = {
        name: '小明',
        age: 12
    }
    getUserInfo(obj)
    
    // 3. -----------------函数类型接口-------------
    interface encrypt {
        (key: string, value: string): string;
    }
    var md5: encrypt = function (key: string, value: string): string {
        return 'md5' + key + value
    }
    var sha1: encrypt = function (key: string, value: string): string {
        return 'sha1' + key + value
    }
    console.log(md5('name', '小明'))
    console.log(sha1('name', '小明'))
    
    // 4.----------可索引接口:对数组的约束-------------
    interface UserArr {
        [index: number]: string;
    }
    var arr: UserArr = ['aaa', 'bbb']
    
    // 5.----------可索引接口:对对象的约束-------------
    interface UserObj {
        [index: string]: any;
    }
    var obj: UserObj = {name: '张三', age: 12}
    
    // 6.----------可索引接口:对类的约束(跟抽象方法很类似)-------------
    interface Animal {
        name: string;
        eat (str: string): void;
    }
    class Dog implements Animal {
        name: string;
        constructor (name: string) {
            this.name = name
        }
        eat () {
            console.log(this.name + '吃狗粮')
        }
    }
    // 7. ----------接口的扩展:接口可以继承接口---------
    interface Animal {
        eat(): void;
    }
    interface Person extends Animal {
        work(): void;
    }
    class Men implements Person {
        public name: string;
        constructor (name: string) {
            this.name = name
        }
        eat () {
            console.log(this.name + '吃馒头')
        }
        work () {
            console.log(this.name + '写代码')
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80

# 泛型

  • 定义:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

  • 示例:

    • 要求函数传入string或number,返回string或number
    // 1. 使用any(缺点,没有类型校验,传入参数类型和返回值类型不能保持一致)
    function foo (arg: any): any {
        return arg
    }
    foo('小明')
    
    // 2. 使用泛型解决该问题
    function foo <T> (arg: T): T {
        return arg
    }
    function bar <T> (arg: T): any {
        return arg
    }
    foo<string>('小明')
    bar<number>(12)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    • 泛型类:比如有个最小堆算法,需要同时支持返回number和string两种类型
    class MinClass<T> {
        public list: T[] = [];
        add (value: T): void {
            this.list.push(vlaue)
        }
        min (): T {
            var minNum = this.list[0]
            for (var i = 0; i < list.length; i++) {
                if (minNum > this.list[i]) {
                    minNum = this.list[i]
                }
            }
            return minNum
        }
    }
    // 实例化类,并指定了T是number
    var m1 = new MinClass<number>()
    m1.add(1)
    m1.add(33)
    m1.add(22)
    console.log(m1.min())
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    • 泛型接口
    // 1. 定义方法一:
    interface Config {
        <T>(key: T, value: T): T
    }
    var config: Config = function <T> (key: T, value: T): T {
        return key + value
    }
    // 调用
    config<string>('name', '张三')
    
    // 2. 定义方法二:
    interface Config<T> {
        (key: T, value: T): T
    }
    function fun<T> (key: T, value: T): T {
        return key + value
    }
    var config: Config<string> = fun
    // 调用
    config('name', '小明')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

# 模块

  • export、import

# 命名空间

namespace A {
    interface Animal {
       name: string;
       eat(): void;
    }
    export class Dog implements Animal {
        name: string;
        constructor (name: string) {
            this.name = name
        }
        eat () {
            console.log(`${this.name}在吃狗粮`)
        }
    }
    export class Cat implements Animal {
        name: string;
        constructor (name: string) {
            this.name = name
        }
        eat () {
            console.log(`${this.name}在吃猫粮`)
        }
    }
}
var d = new A.Dog('柯基')
d.eat()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 装饰器

  • 定义:装饰器是一种特殊类型的声明,他能够被附加到类声明、方法、属性,可以修改类的行为,通俗来讲,装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
  • 常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器
  • 装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)

# 类装饰器

  • 普通装饰器(不可传参)
// 装饰器
function logClass(params: any) {
    // params就是当前类
    console.log(params)
    
    params.prototype.apiUrl = '动态扩展的属性'
    params.prototype.run = function () {
        console.log('run...')
    }
}
@logClass
class HttpClient {
    constructor () {
    }
    getData () {
    }
}

/* 打印:
	http实例类
*/
var http = new HttpClient()
/* 打印:
	动态扩展的属性
*/
console.log(http.apiUrl)
/* 打印:
	run...
*/
http.run()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • 装饰器工厂(可传参)
function logClass(params: string) {
    // 返回一个函数
    return function (target: any) {
        // target是当前类、params是传入的参数
        console.log(target)
        console.log(params)
        target.prototype.apiUrl = params
    }
}
@logClass('http://127.0.0.1:8080')
class HttpClient {
    constructor () {}
    getData () {}
}

/* 打印:
	http实例类
	http://127.0.0.1:8080
*/
var http: any = new HttpClient()
/* 打印:
	http://127.0.0.1:8080
*/
console.log(http.apiUr)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • 构造函数重载
function logClass (target: any) {
    // 返回一个类
    return class extends target {
        apiUrl: any = '我是修改后的url'
        getData () {
            console.log(this.apiUrl)
        }
    }
}
@logClass
class HttpClient {
    public apiUrl: string;
    constructor () {
        this.apiUrl = '我是url'
    }
    getData () {
        console.log(this.apiUrl)
    }
}

var http: any = new HttpClient()
/* 打印:
	我是修改后的url
*/
console.log(http.apiUr)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 属性装饰器

function logProperty (params: any) {
	// 返回一个函数
    return function (target: any, attr: any) {
        // target是当前类、attr是当前属性名、params是传入的参数
        console.log(target)
        console.log(attr)
        target[attr] = params
    }
}

class HttpClient {
    @logProperty('http://www.liang2uv.top')
    public url: string;
    constructor () {
    }
    getData () {
        console.log(this.url)
    }
}

/* 打印:
	http实例类
	url
*/
var http: any = new HttpClient()
/* 打印:
	http://liang2uv.top
*/
console.log(http.url)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 方法装饰器

function logMethod (params: any) {
    // 返回一个函数
    return function (target: any, methodName: anym desc: any) {
        // target是当前类、methodName是当前方法名称、desc是成员的属性描述符,params是传入的参数
        console.log(target)
        console.log(methodName)
        console.log(desc.value)
        
        // 修改当前类的属性和方法
        target.apiUrl = 'xxxx'
        target.run = function () {
            console.log('run...')
        }
        
        // 修改当前方法
        var oMethod = desc.value
        desc.value = function (...args: any[]) {
            args = args.map(value => String(value))
            oMethod.apply(this, args)
        }
    }
}
class HttpClient {
    public url: string;
    constructor () {
    }
    @get('http://www.liang2uv.top')
    getData (...args: any[]) {
        console.log(args)
        console.log('我是getData方法')
    }
}
/* 打印:
	http实例类
	getData
	getData () {
        console.log(this.url)
    }
*/
var http: any = new HttpClient()
/* 打印:
	xxxx
*/
console.log(http.apiUrl)
/* 打印:
	run...
*/
http.run()
/* 打印:
	['123', 'xxxx']
	我是getData方法
*/
http.getData(123, 'xxxx')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#TypeScript
上次更新: 2021/11/09, 14:11:00
小程序笔记
数据结构笔记

← 小程序笔记 数据结构笔记→

最近更新
01
第十章:排序
11-05
02
第九章:查找
11-05
03
第八章:图
11-05
更多文章>
Theme by Vdoing | Copyright © 2020-2021 Liang2uv | 桂ICP备19012079号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式