1、TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准(ES6 教程)。
2、TypeScript 由微软开发的自由和开源的编程语言。
3、TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

JavaScript 与 TypeScript 的区别:

1、TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。
2、TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

1、TypeScript作用域问题

  1. // 如果我们在一个ts文件中添加了一个全局变量,那么在其他ts文件中就不能再去声明这个变量了
  2. // 例:
  3. 1.ts
  4. const a = 123
  5. 2.ts
  6. const a = '123'
  7. // 2.ts文件中就会报出,a已经声明过了,不能再声明
  8. // 解决办法:
  9. // 我们可以把2.ts作为一个模块导出,export {},因为模块是有单独作用域的,所以和1.ts文件不会产生冲突

2、Object类型

object类型并不是单只对象类型,而是泛指所有的非原始类型。也就是对象、数组、函数

  1. // 例:
  2. const foo: object = // 可是是函数 function() {}、数组[]、对象{}
  3. // 如果要单独定义对象的话,可以使用
  4. const foo: {} = {}
  5. // 如果要单独针对对象里面的字段进行定义的话,可以使用
  6. const foo: {name: string, age: number} = { name: 'jack', age: 23 }
  7. // 注意:定义的对象必须要跟我们定义的变量的解构完全一致,否则会报错

3、数组类型

  1. const foo: Array<number> = [1,2,3] // 表示定义一个数组中只能是数字的变量,其他会报错
  2. // 或
  3. const foo: number[] = [1,2,3]
  4. // 例子:计算一个数组的和,但是传的值必须是数字
  5. function sum(...args: number[]) { // 代表必须全部是由数字组成的数组类型
  6. return args.reduce((prev, current) => {
  7. return prev + current
  8. }, 0)
  9. }
  10. console.log(sum(1,2,3,4,5)) // 15

4、元组类型

明确元素数量以及每个元素类型的一个数组

  1. // 例子:
  2. const arr: [name: string, age: number] = [name: 'jack', age: 23]
  3. // 这种就是元组类型

5、枚举类型

  1. enum upOrDown {
  2. down = 0,
  3. up = 1
  4. }
  5. // 定义枚举
  6. // 或
  7. enum upOrDown {
  8. down,
  9. up
  10. }
  11. // 默认从0开始网上递增
  12. // 如果定义的值不是数字,那就必须的写上对应的值
  13. const goods = {
  14. name: '天猫精灵',
  15. price: 99,
  16. index: upOrDown.down // 0 未上架、1 已上架
  17. }
  18. // 通过upOrDown.dowm / upOrDown.up拿到对应的类型
  19. // 注意:枚举类型会影响到我们编译后的结果
  20. // 上面代码编译后对应的js文件会变成如下
  21. var upOrDown;
  22. (function (upOrDown) {
  23. upOrDown[upOrDown["down"] = 0] = "down";
  24. upOrDown[upOrDown["up"] = 1] = "up";
  25. })(upOrDown || (upOrDown = {}));
  26. const goods = {
  27. name: '天猫精灵',
  28. price: 99,
  29. index: upOrDown.down // 0 未上架、1 已上架
  30. };
  31. // 如果不想这样做的话我们可以定义 const
  32. const enum upOrDown {
  33. down,
  34. up
  35. }
  36. // 编译后:
  37. const goods = {
  38. name: '天猫精灵',
  39. price: 99,
  40. index: 0 /* down */ // 0 未上架、1 已上架
  41. };

6、函数类型

  1. // 函数定义的方式有两种:函数声明、函数表达式
  2. // 1、函数声明
  3. function foo(name: string, age: number): string {
  4. return `my name is ${name}, age ${age}`
  5. }
  6. foo('jack', 23)
  7. /**
  8. * 1、foo函数我们定义了两个参数,那么我调用foo方法的时候也必须传两个参数,不能多也不能少
  9. * 2、并且这两个参数我们分别定义了name必须为字符串类型,age必须为数字类型。如果我们传入的
  10. * 是其他类型也会报错
  11. * 3、我们还定义了返回值必须为string类型,如果返回的是其他类型也会报错
  12. * 4、如果我们定义可选参数可以在参数名后面加上'?',例子:age?: number。注意:可选参数必须定义在参数 * 的最后
  13. */
  14. // 2、函数表达式
  15. const foo = function(name: string, age: number): string {
  16. return `my name is ${name}, age ${age}`
  17. }
  18. foo('jack', 23)
  19. /*
  20. * 1、接受函数的这个变量也是有类型的,比如我们现这个函数返回的是一个字符串,那么这个foo变量应该就是
  21. * string类型
  22. * 2、如果我们在编辑器中写上函数的话,会提示const foo: (name: string, age: number) => string
  23. */

7、任意类型(any)

any是动态类型可以接受任意的值,不会报任何语法上的错误,any是不安全的,所以不要轻易的去使用

  1. function foo (value: any) {
  2. console.log(value)
  3. }
  4. foo(12)
  5. foo('string')
  6. foo(true)
  7. // 以上定义的any类型所有值都可以接受

8、隐式类型推断

隐式类型推断就是你在定义一个变量或者其他的时候,如果你没有给它定义类型,它会根据你的代码或者值推断出其类型

  1. let age = 18
  2. /**
  3. * 比如你定义一个age = 18的变量,在编辑器中你会看到这样一个注解:let age: number
  4. * 意思就是定义了一个变量age,类型是number类型
  5. */
  6. // 如果你将这个变量重新赋值,例:
  7. age = '123'
  8. // 这样的话编辑器中就会报:let age: number,不能将类型“string”分配给类型“number”。

建议:给每个变量添加明确的类型,这样便于后期理解我们的代码

9、类型断言(as)

类型断言的意思就是说:使用者非常确定我们定义的值是什么类型,但是代码并不确定。这个时候我们就可以使用断言的方式告诉代码,我们定义的是什么类型

  1. const list = [1, 2, 3, 4, 5] // 定义一个变量全是数字的数组
  2. const res = list.find(i => i > 0) // 获取数组中第一个大于0的数字,返回的肯定是一个数字
  3. const result = res * res // 这个时候代码中会提示:const res: number | undefined,意思就是说res是个数字也有可能是 undefined,所以我们就不能是 * 来进行计算
  4. 解决方法:使用断言的方式
  5. const num = res as number // 断言res一定是一个number类型
  6. const result = res * res // 这样计算就不会出现代码报错的问题

10、接口(interface)

接口就是用来约束一个对象的结构,一个对象去实现一个接口,那它就必须去拥有这个接口当中的所有成员,以及对应成员的类型

  1. function foo (person) {
  2. console.log(person.name)
  3. console.log(person.age)
  4. }
  5. // 这个时候person就会报:(parameter) person: any
  6. // 这个时候我们可以给这个参数定义一个接口
  7. interface Person {
  8. name: string
  9. age: number
  10. }
  11. function foo (person: Person) {
  12. console.log(person.name)
  13. console.log(person.age)
  14. }
  15. foo({
  16. name: 'jack',
  17. age: 23
  18. })
  19. /*
  20. * 我们在调用这个方法的时候,就必须得传一个对象,这个对象就必须得包含name和age
  21. * 并且name是string类型,age是number类型,否则会报语法错误
  22. */
  23. // 接口中还可以定义:可选成员、只读成员、动态成员
  24. // 可选成员:就是说我们定义的接口中字段可以有也可以是undefined,例:
  25. interface Person {
  26. name: string
  27. age: number
  28. work?: string // 我们可以在work后面加一个 ? 来体现出我们这个字段是可选值
  29. }
  30. // 只读成员:就是说我们定义的字段是不能修改的
  31. interface Person {
  32. name: string
  33. age: number
  34. work?: string
  35. readonly sex: string // 这个就是我们定义的成员只能读取,不能修改
  36. }
  37. // 动态成员:在我们不确定的情况我们可以定义动态成员
  38. interface Person {
  39. [key: string]: string // key就是我们定义的键,类型为string,后面的string是值的类型
  40. }
  41. const person: Person = {
  42. }
  43. 这样我们就可以随意的想person对象中添加值
  44. person.name = 'jack'
  45. person.sex = '男'

11、类

描述:类就是一个具体事物的抽象特征,TypeScript中的类其实和js中的类差不多

  1. // 1、基本使用
  2. class Person {
  3. name: string
  4. age: number
  5. // 以上是和js的区别,我们如果要在构造函数中是this的话,必须在上面定义一个对应的值
  6. constructor(name: string, age: number) {
  7. this.name = name
  8. this.age = age
  9. }
  10. sayHi(msg: string): void {
  11. console.log(`I am ${this.name}`)
  12. }
  13. }
  14. // 类的访问修饰符
  15. 1private(私有属性)
  16. class Person {
  17. name: string
  18. private age: number // 如果我们在age上面定义了一个private私有属性的话,那这个age只能在类的内部去访问
  19. constructor(name: string, age: number) {
  20. this.name = name
  21. this.age = age
  22. }
  23. sayHi(msg: string): void {
  24. console.log(`this is ${this.name}`)
  25. console.log(`this is ${this.age}`) // 可以访问到age属性
  26. }
  27. }
  28. const jack = new Person('name', 18)
  29. console.log(jack.name) // 可以访问到name属性
  30. console.log(jack.age) // 访问不到age属性
  31. 2public(公有属性)
  32. class Person {
  33. public name: string // 不加public默认就是public,建议添加,这样便于后期代码的可读性
  34. private age: number // 如果我们在age上面定义了一个private私有属性的话,那这个age只能在类的内部去访问
  35. constructor(name: string, age: number) {
  36. this.name = name
  37. this.age = age
  38. }
  39. sayHi(msg: string): void {
  40. console.log(`this is ${this.name}`)
  41. console.log(`this is ${this.age}`) // 可以访问到age属性
  42. }
  43. }
  44. const jack = new Person('name', 18)
  45. console.log(jack.name) // 可以访问到name属性
  46. console.log(jack.age) // 访问不到age属性
  47. 2protected(受保护的)
  48. // 只能在子类中访问到,外部也是访问不到的,这是和private的区别
  49. class Person {
  50. public name: string // 不加public默认就是public,建议添加,这样便于后期代码的可读性
  51. private age: number // 如果我们在age上面定义了一个private私有属性的话,那这个age只能在类的内部去访问
  52. protected gender: true
  53. constructor(name: string, age: number) {
  54. this.name = name
  55. this.age = age
  56. this.gender = true
  57. }
  58. sayHi(msg: string): void {
  59. console.log(`this is ${this.name}`)
  60. console.log(`this is ${this.age}`) // 可以访问到age属性
  61. console.log(`this is ${this.gender}`) // 可以访问到gender属性
  62. }
  63. }
  64. class Student extends Person {
  65. constructor(name: string, age: number) {
  66. super(name, age)
  67. console.log(this.gender) // 能访问到gender属性
  68. }
  69. }
  70. const jack = new Person('name', 18)
  71. console.log(jack.name) // 可以访问到name属性
  72. console.log(jack.age) // 访问不到age属性
  73. console.log(jack.gender) // 访问不到gender属性
  74. 注意:如果在构造函数上使用private方法,那这个类型就不能在外部被实例化
  75. class Student extends Person {
  76. private constructor(name: string, age: number) {
  77. super(name, age)
  78. console.log(this.gender)
  79. }
  80. }
  81. const tom = new Student() // 无法实例化
  82. 解决方法:
  83. class Student extends Person {
  84. private constructor(name: string, age: number) {
  85. super(name, age)
  86. console.log(this.gender)
  87. }
  88. // 添加静态方式去返回这个实例对象
  89. static create (name: string, age: number) {
  90. return new Student(name, age)
  91. }
  92. }
  93. const tom = Student.create('tom', 18) // 这样就可以create静态方法去创建实例对象了