SunJianXu Blog SunJianXu Blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《JavaScript DOM 编程艺术》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《React》笔记
    • 《Git》学习笔记
    • 《TypeScript》学习笔记
  • HTML
  • CSS
后端
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

SunJianXu

前端界的小学生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《JavaScript DOM 编程艺术》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《React》笔记
    • 《Git》学习笔记
    • 《TypeScript》学习笔记
  • HTML
  • CSS
后端
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • JavaScript

  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《JavaScript DOM编程艺术》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《React》笔记
    • 《Git》学习笔记
    • TypeScript笔记
      • 常见数据类型
      • 枚举类型
      • 接口
      • 函数类型和混合类型接口
      • 函数相关知识点
      • ES6 中的 class
      • ts 中的类
      • 抽象类
      • 类与接口的关系
      • 泛型函数
      • 泛型接口
      • 泛型类
      • 泛型约束
      • 命名空间
        • name.ts 文件
        • index.ts 文件
  • 前端
  • 学习笔记
sunjianxu
2020-10-08

TypeScript笔记

# TypeScript 学习笔记

# 常见数据类型

/**
 * ts数据类型
 */
console.warn('*************数据类型**********************')
// 字符串类型
let str_: string = '字符串类型'
console.log(str_, 'string')

let number: number = 123
console.log(number, 'number类型')

// 布尔类型
let bool_: boolean = true
console.log(bool_, 'boolean')

// undefined 类型
let un_: undefined = undefined
console.log(un_)

// null 类型
let _null: null = null
console.log(_null)

// 数组单类型
let arr_: Array<number> = [1, 2, 3, 4, 5, 6]
let arr_3: number[] = [7, 8, 9, 10]
console.log(arr_, arr_3, 'Array')

// 数组多类型
let arr_2: Array<number | string> = [1, 2, 3, 4, 5, 6, 'string']
console.log(arr_2, 'Array')

// 元组类型
let _arr: [number, string] = [111, 'sting']

// _arr.push(223665); // 可以push,但是不可访问
// console.log(_arr[2])

// 对象类型

// let obj_:object = {name:'leon',age:18}; // 这种方式生命不可修改成员
// obj_.name = "ceshi";
let obj_: { name: string; age: number } = { name: 'leon', age: 18 }
obj_.name = 'update_name'
console.log(obj_)

// 函数类型
let sums = (x: number, y: number): number => x + y //声明函数类型模型,并对函数进行具体实现
console.log(sums(12, 36))

let compute_: (x: number, y: number) => number //声明函数类型模型,但未对函数进行具体实现
compute_ = (a, b) => a + b //对函数的具体实现
console.log(compute_(1, 2))

// symbol 类型

let s1_: symbol = Symbol()
let s2_ = Symbol()
console.log(s1_)
console.log(s2_)
console.log(s1_ === s2_)

// void 类型(没有任何返回值的类型)
let v_ = () => {}
console.log(v_)

// any 类型(任意类型)
let any_
any_ = 1
any_ = 'string'
console.log(any_)

// never 类型(永远不会有返回值)
let err_ = () => {
  throw new Error('错误啦!')
}

let endless_ = () => {
  while (true) {}
}

console.log(endless_)
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
81
82

# 枚举类型

/**
 * typescript 枚举类型 (enum)
 * 知识点: 枚举类型、枚举成员类型,以及常量枚举的应用场景
 */

//   数字类型枚举 // 可通过值访问,也可以通过key 访问

console.warn('*******************枚举类型*****************')
enum role {
  admin,
  role_one,
  role_two,
}

// role[0] = '11' 不允许修改

//  字符串枚举
enum Message {
  success = '成功!',
  error = '失败了',
}
console.log(Message['success'])

// 异构枚举
enum Ygou {
  admin,
  message = '失败了',
}

console.log(Ygou)

//  枚举成员的类型
enum Leixing {
  // const 类型(编译阶段就会执行)
  admin,
  a = Message.success,
  b = 1 + 3,

  // computed (会等到执行阶段运行)
  c = Math.random(),
  d = '12456'.length,
}

console.log(Leixing)

// 常量枚举(特点:会在编译阶段被移除);应用场景:只用到值,而不需要变量

const enum Dua {
  Admin,
  E,
  d,
}
let min_ = [Dua.Admin, Dua.E, Dua.d]
console.log(min_)

// 枚举类型作为数据的类型
enum Test1 {
  a,
  b,
} // 数字枚举
enum Test2 {
  a = 1,
  b = 2,
} // 数字枚举
enum Test3 {
  a = 'success',
  b = 'error',
} // 字符串枚举

console.log(Test1, 'Test1')
console.log(Test2, 'Test2')
console.log(Test3, 'Test3')

let test1: Test1 = 11 //赋值可超过枚举类型的范围

let test2: Test2 = 1024
let test3: Test3 = Test3.a
let test4: Test3 = Test3.b

console.log(test1)
console.log(test2)
console.log(test3)
console.log(test4)

// 枚举成员类型作为数据的类型

let t1: Test1.a = 1
let t2: Test1.b = 1
let t3: Test1.a = 102
// console.log(t1,t2,t1 === t2)  // 不同类型的枚举成员类型的数据不可以进行比较
console.log(t1, t3, t1 === t3)

let t4: Test3.a = Test3.a // 字符串枚举类型的枚举成员类型只能是枚举成员类型的自身
let t5: Test3.b = Test3.b

console.log(t4, t5)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

# 接口

/**
 * 接口 接口是约束 对象、函数、类的结构和类型的一种契约
 * 对象类型接口
 */

/**
 * 跳过严格的类型检查的方式
 * 字面量的类型断言
 * as 类型断言
 * 字符串索引签名
 */

console.warn('***********************对象类型接口**********************')
;(() => {
  // 定义接口
  interface List {
    id: number
    name: string
    // [x:string]:any;  // 字符串索引签名可跳过严格的类型检查
  }

  interface Result {
    data: List[]
  }

  function handleRender(result: Result) {
    result.data.forEach((item) => {
      console.log(item.id, item.name)
    })
  }

  const result_2 = {
    data: [
      { id: 1, name: 'leon' },
      { id: 2, name: 'lisi', sex: 'man' },
    ],
  }

  // 语法一: 类型断言,明确告诉编译器就是这个类型的
  handleRender({
    data: [
      { id: 1, name: 'leon' },
      { id: 2, name: 'lisi', sex: 'man' },
    ],
  } as Result) // as Result  类型断言,明确告诉编译器就是这个类型的

  // 语法二: 类型断言,明确告诉编译器就是这个类型的,这种写法在react中有歧义
  handleRender(<Result>{
    data: [
      { id: 1, name: 'leon' },
      { id: 2, name: 'lisi', sex: 'man' },
    ],
  }) // as Result  类型断言,明确告诉编译器就是这个类型的
})()

console.log('***************-----------**********')

// 可选属性
;(() => {
  // 定义接口
  interface List {
    id: number
    name: string
    sex?: string // 定义可选属性
    // [x:string]:any;  // 字符串索引签名可跳过严格的类型检查
  }

  interface Result {
    data: List[]
  }

  function handleRender(result: Result) {
    result.data.forEach((item) => {
      console.log(item.id, item.name)
      if (item.sex) {
        console.log(item.sex)
      }
    })
  }

  // 语法一: 类型断言,明确告诉编译器就是这个类型的
  handleRender({
    data: [
      { id: 1, name: 'leon' },
      { id: 2, name: 'lisi', sex: 'man' },
    ],
  })
})()

// 只读属性
;(() => {
  // 定义接口
  interface List {
    readonly id: number // 只读属性
    name: string
    sex?: string // 定义可选属性
    // [x:string]:any;  // 字符串索引签名可跳过严格的类型检查
  }

  interface Result {
    data: List[]
  }

  function handleRender(result: Result) {
    result.data.forEach((item) => {
      // item.id++;
      console.log(item.id, item.name)

      if (item.sex) {
        console.log(item.sex)
      }
    })
  }

  // 语法一: 类型断言,明确告诉编译器就是这个类型的
  handleRender({
    data: [
      { id: 1, name: 'leon' },
      { id: 2, name: 'lisi', sex: 'man' },
    ],
  })
})()

// 可索引类型接口
;(() => {
  console.log('可索引类型接口')

  // 下标类型索引
  interface StringArray {
    [index: number]: string
  }
  let data: StringArray = ['test1', 'test2']
  console.log(data[0])

  // 字符串索引类型接口
  interface Names {
    [x: string]: any
    [y: number]: string
  }
  let re_: Names = {
    name: '名称',
  }
  let re_2: Names = ['测试33']
  console.log(re_.name)
  console.log(re_2[0])
})()
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

# 函数类型和混合类型接口

/**
 * 函数类型和混合类型接口
 */
console.warn('***********函数类型接口和混合类型接口***************')
// 函数类型接口
let f1_: (x: number, y: number) => number // 变量定义函数
f1_ = (a, b) => a + b //函数的具体实现
console.log(f1_(2, 3))

// 接口定义函数
interface Add_ {
  (x: number, y: number): number
}

let add_: Add_ = (a, b) => a + b // 函数的具体实现
console.log(add_(1, 2))

//  类型别名定义函数
type add_2 = (x: number, y: number) => number
let handleAdd: add_2 = (a, b) => a + b
console.log(handleAdd(11, 33))

// 混合类型接口,一般用于构造函数(定义一些类库,包含函数和属性成员和方法)
interface Lib {
  (): void
  version: string
  doSometing(): void
}
// 定义构造函数生成lib
function generatorLib(version: string) {
  let lib: Lib = (() => {}) as Lib // 类型断言
  lib.version = version
  // lib.doSomething = () => {
  //   console.log('action' + version)
  // }
  return lib
}

let g1_ = generatorLib('1.0.0')
console.log(g1_, 'g1***********')
console.log(g1_.version)
// g1_.doSomething();

let g2_ = generatorLib('1.0.1')
console.log(g2_, 'g2***********')
console.log(g2_.version)
// g2_.doSomething();
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

# 函数相关知识点

/**
 * 函数相关知识点
 */
console.warn('**********函数相关知识点**********')
// 函数的定义
// 1 function 字面量定义
function handleAdd_(x: number, y: number): number {
  return x + y
}
console.log(handleAdd_(8, 9), '字面量定义')

// 2 变量定义函数
let handleAdd_2: (x: number, y: number) => number
handleAdd_2 = (a, b) => a + b
console.log(handleAdd_2(1, 2), '变量定义函数')

// 3 类型别名定义函数  type
type handleAdd_3_ = (x: number, y: number) => number
let aa: handleAdd_3_ = (a, b) => a + b
console.log(aa(3, 6), '类型别名定义函数  type')

// 4 接口定义函数
interface Lib_ {
  (x: number, y: number): number
}
let ceshi: Lib_ = (a, b) => a + b
console.log(ceshi(2, 6))

// 可选参数
function handleParams(x: number, y?: number) {
  return y ? x + y : x
}
console.log(handleParams(120), '可选参数')

// 默认参数
function handleDefaultParams(x: number, y = 10) {
  return x + y
}
console.log(handleDefaultParams(10), '默认参数')

// 剩余参数
function handleRestParams(x: number, ...rest: number[]) {
  return x + rest.reduce((pre, cur) => pre + cur)
}
console.log(handleRestParams(1, 2, 3, 4, 5), '剩余参数')

// 函数重载(要先对重载的函数列表声明,然后在宽松的版本中实现)
function handleReload(...rest: number[]): number
function handleReload(...rest: string[]): string
function handleReload(...rest: any[]): any {
  const first = rest[0]
  if (typeof first === 'number') {
    return rest.reduce((pre, cur) => pre + cur)
  }
  if (typeof first === 'string') {
    return rest.join('-')
  }
}

console.log(handleReload(1, 2, 3, 4, 5), '函数重载')
console.log(handleReload('react', 'router'), '函数重载')
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

# ES6 中的 class

console.warn('ES6中的class********')
class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  sayHello() {
    console.log('hello')
  }
}

class American extends Person {
  constructor(name, age) {
    super(name, age) // 指向的就是父类的构造器,也就是 Person.prototype.constructor
  }
}
class Chinese extends Person {
  constructor(name, age, id) {
    super(name, age)
    this.id = id //实例属性
  }
  fs() {
    //实例方法
    console.log(88)
  }

  // static info = "info"  //es6 中明确规定 只有static 只可以声明静态方法,不可以声明静态属性
  // // es7 中有静态属性提案,可以用babel 转换  也可以用Chinese.xx = 'xx' 一个静态属性
  // static show() {  //静态方法
  //   console.log("show")
  // }
}

const p1 = new American('koa', 21)
const p2 = new Chinese('zs', 24, 120335)
console.log(p1)
p1.sayHello()
console.log('--------------------------')
const p = new Person('测试', 21)
console.log(p)
console.log(p2)
// p2.sayHello()
// Chinese.show()
// console.log(Chinese.info)
// p2.fs()
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

# ts 中的类

console.warn('**********ts中的类************')

// 类的基本实现
class Dog_ {
  constructor(name: string) {
    this.name = name
  }
  name: string // 类的属性必须初始化
  eay() {
    console.log('吃吃吃')
  }
}
const d1 = new Dog_('jack')
console.log(d1)

class Done {
  constructor(public status: boolean) {
    // 通过成员修饰符可以省去 初始化类的属性
    this.status = status
  }
  changeStatus() {
    this.status = false
  }
}
const done = new Done(true)
console.log(done)
done.changeStatus()
console.log(done)

// 类的继承
class Father {
  constructor(public name: string, public age: number) {
    this.name = name
    this.age = age
  }
  sayHello() {
    console.log('hello')
  }
}
class Child extends Father {
  constructor(public name: string, public age: number, public sex: string) {
    super(name, age)
    this.sex = sex
  }
}
const c1 = new Child('leon', 24, 'male')
console.log(c1)
c1.sayHello()

/**
 * 成员修饰符
 * 公有成员
 * 私有成员
 * 受保护成员
 * 只读成员
 * 静态成员
 */

// 公有成员  public
class Test {
  constructor(public name: string) {
    this.name = name
  }
}
class Test2_ {
  constructor(name: string) {
    this.name = name
  }
  public name: string
}

// 私有成员 private(只能在类的里面使用,不能被实例和子类调用,可以理解为有块级作用域)

//  成员私有
class Test3_ {
  constructor(public name: string) {
    this.name = name
    this.pay()
  }
  private pay() {
    console.log('这是私有成员方法pay')
  }
}

const t3_ = new Test3_('测试机')
// t3_.pay() 不能被实例调用

// 构造函数私有(不能实例化,也不能被子类调用)

class Test4 {
  // 构造函数私有,不能实例化,也不能继承
  private constructor(public name: string) {
    this.name = name
  }
}

// const ts_4 = new Test4('ce');
// 父类的构造函数私有,即不能被子类继承

// class Test5 extends Test4 {
//   constructor(public name:string) {
//     super(name);
//   }
// }

//  受保护成员 protected(如果声明在构造器,则代表只能用做继承,而不能实例化,也就是基类)
class Test6 {
  constructor(public name: string) {
    this.name = name
    this.pro()
  }
  protected pro() {
    console.log('这是受保护成员,只能在类和子类中使用,不能被实例使用')
  }
}

const t6_ = new Test6('protected')
console.log(t6_)

class Test7 extends Test6 {
  constructor(public name: string, public color: string) {
    super(name)
    this.color = color
    this.pro()
  }
}
const t7_ = new Test7('test7', 'red')
console.log(t7_)

// 只读成员 readonly
class Test8 {
  constructor(public name: string) {
    this.name = name
  }
  readonly uid: number = 2018
}
const t8_ = new Test8('Test8')
// t8_.uid = 2019; 只能访问,不能修改

// 静态成员 static(只能类本身通过类名调用,也可以被继承,也就是说,子类也可以通过类名 进行访问调用)
class Test9 {
  constructor(public name: string) {
    this.name = name
  }
  static user_id: number = 2016
}
const t9_ = new Test9('测距hi及')
console.log(t9_)
console.log(Test9.user_id)

class Test10 extends Test9 {
  constructor(public name: string) {
    super(name)
  }
}
const t10_ = new Test10('测距hi及')
console.log(Test10.user_id)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

# 抽象类

console.warn('*********抽象类***********')

// 抽象类(只能被继承,不能被实例化,像基类)
abstract class Animal_ {
  constructor(public name: string) {
    this.name = name
  }
  eat() {
    console.log('bonnes')
  }
}
// const a1_ = new Animal_() // 不能被实例化

class Cat_ extends Animal_ {
  constructor(public name: string) {
    super(name)
  }
}
const c1_ = new Cat_('猫🐱')
console.log(c1_)

// 多态(在父类中定义抽象方法,但并不对方法做出具体实现,而是在多个子类中做出具体的方法实现)

abstract class Animals {
  constructor(public name: string) {
    this.name = name
  }
  abstract seep(): void // 父类定义抽象方法
}
class Dog_2 extends Animals {
  constructor(public name: string) {
    super(name)
  }
  seep() {
    console.log('这是dog的seep')
  }
}

class Cat_2 extends Animals {
  constructor(public name: string) {
    super(name)
  }
  seep() {
    console.log('这是cat的seep')
  }
}

const d1_ = new Dog_2('dog')
console.log(d1_)
d1_.seep()

const cat_ = new Cat_2('cat_')
console.log(cat_)
cat_.seep()

let animals_: Animals[] = [d1_, cat_] // 声明类的数组变量
animals_.forEach((item) => {
  item.seep()
})
// ts 特殊类型 this 类型,可用于链式操作

class Flow {
  seep1() {
    console.log('flow-seep1')
    return this
  }
  seep2() {
    console.log('flow-seep2')
    return this
  }
}

new Flow().seep1().seep2() // 因为返回了this,所以可以进行链式操作

// this 类型的多态表现(可以调用父类的方法也可以调用子类的方法)
class Child_ extends Flow {
  constructor() {
    super()
  }
  next() {
    return this
  }
}
new Child_()
  .seep2()
  .next()
  .seep1()
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
81
82
83
84
85
86
87

# 类与接口的关系

console.warn('********类与接口的关系********')

/**
 *
 * 接口只能约束类的公有成员 也就是 public
 */

//  类实现接口
interface Lib_3 {
  name: string
  eat(): void
}

// 类实现接口的时候,成员只能多不能少,并且接口只能限制类的公有成员
class Trst implements Lib_3 {
  constructor(public name: string) {
    this.name = name
  }
  eat() {
    console.log('吃')
  }
  seep() {}
}

// 接口的相互继承
// 单一的接口继承
interface Inter0 extends Lib_3 {
  age: number
}
class Test36 implements Inter0 {
  constructor(public name: string, public age: number) {
    this.name = name
    this.age = age
  }
  eat() {
    console.log(258)
  }
}

interface bog {
  height: number
}

// 多个的接口继承
interface InterC extends Inter0, bog {
  sex: string
}
class Test360 implements InterC {
  constructor(
    public name: string,
    public age: number,
    public sex: string,
    height: number
  ) {
    this.name = name
    this.age = age
    this.sex = sex
    this.height = height
  }
  height: number
  eat() {
    console.log(258)
  }
}

// 接口继承类(这过程就是把类的成员抽离出来,可以抽离的成员有公有成员,私有成员和受保护成员)
class Auto_ {
  status = 0
}
// 等于把Auto_类的结构抽离出来了放在接口Aufou 上面了
interface Aufou extends Auto_ {}

// 实现
class Cur_ implements Aufou {
  status: 10
}

// 子类实现接口

class Ceshi extends Auto_ implements Aufou {}
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

# 泛型函数

console.warn('****** 泛型函数 *****')
//  实现一个函数可以接收字符串也可以接收一个字符串数组

// 联合类型的函数
function log_(str: string | string[]): string | string[] {
  console.log(str)
  return str
}
log_('test')
log_(['test1', 'test2'])

// 函数重载实现
function reloadLog(str: string): string
function reloadLog(str: string[]): string[]
function reloadLog(str: any): any {
  console.log(str)
  return str
}
reloadLog('测试机')
reloadLog(['测试机', '测试机2'])
// any类型

function handleAnyParams(str: any): any {
  // 语法预知传进来的参数和返回值是什么类型,无法约束
  console.log(str)
  return str
}
handleAnyParams(112)
handleAnyParams({ any: '任意的类型' })

// 泛型函数实现
function handleT<T>(str: T): T {
  console.log(str)
  return str
}
handleT<string>('这是泛型函数实现的') //<string> 可以省略
handleT<object>({
  message: '这是泛型函数实现的',
})

// 泛型定义函数的类型
type LogT = <T>(str: T) => T

let handleLogT: LogT = (s) => {
  console.log(s)
  return s
}

handleLogT('这是泛型定义的函数类型')
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

# 泛型接口

console.log('*****泛型接口******')
// 定义泛型接口
interface Libs_ {
  <T>(x: T): T
}
let Obj: Libs_ = <T>(x: T): T => {
  console.log(x)
  return x
}
console.log('定义泛型接口')
Obj(2)

// 泛型接口约束 单一成员 和 约束所有成员
// 约束单一成员
interface Libs_2 {
  <T>(x: T): T
}

let Obj2: Libs_2 = <T>(x: T): T => {
  console.log(x)
  return x
}

console.log('定义泛型接口')
Obj2(20)

// 约束所有成员(约束函数和所有成员);
interface UDI<T> {
  (value: T): T
}
let apps: UDI<number> = <T>(x: T): T => x

// 设置泛型接口的默认类型
interface De<T = number> {
  (value: T): T
}

let de: De<string> = <T>(x: T): T => x
de('258')

let de2: De = <T>(x: T): T => x
de2(36)
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

# 泛型类

console.warn('******泛型类*******')

class Logs<T> {
  run(value: T) {
    console.log(value)
  }
}
const logs = new Logs<number>()
logs.run(257)
1
2
3
4
5
6
7
8
9

# 泛型约束

console.warn('*******泛型约束******')
class Logs2<T> {
  run(value: T) {
    console.log(value)
  }
}
// const logs2 = new Logs2<number>();
const logs2 = new Logs2() // 不明文设定类型的话,代表是any
logs2.run(369)
logs2.run('测试机')

// 泛型约束
interface Length {
  length: number
}

// 定义泛型约束,代表着传入的参数必须是带有length 属性
function system<T extends Length>(value: T): T {
  return value
}

console.log(system([]))
console.log(system({ length: 258 }))
console.log(system('123'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 命名空间

# name.ts 文件

namespace Lib {
  export function eatApple() {
    console.log('吃苹果啦!')
  }
}
1
2
3
4
5

# index.ts 文件

/// <reference path="name.ts" />

console.warn('命名空间')
// namespace 声明命名空间的关键字
// 存在于不同文件的相同名称的命名空间,会自动合并在一起
namespace Lib {
  let version = '1.0.1'
  export function sayHello() {
    console.log('hello', version)
  }
  export function sayHi() {
    console.log('hi', version)
  }
}
Lib.sayHello()
Lib.sayHi()
// Lib.eatApple(); // 编译过后可在全局环境执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
编辑 (opens new window)
#TypeScript
上次更新: 2021/08/03 20:55:47
《Git》学习笔记

← 《Git》学习笔记

最近更新
01
解决 ios10 及以上 Safari 无法禁止缩放的问题
08-31
02
获取页面视口大小
08-21
03
数组扁平化
08-20
更多文章>
Theme by Vdoing | Copyright © 2019-2021 SunJianXu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×