vscode 原生支持ts编译
在vscode 里 上部,终端下的运行任务中,有选择 typescript ,可以选择构建或者监听。
构建:是指一次 打包
监听:是每一次保存之后都会自动打包

在package.json中 表示可以通过指令完成

“scripts”: {
“build”:”tsc”,
“watch”:”tsc —watch”
}

问题

当你新建了一个 变量时 ,提示无法重新声明块范围变量“name”。
说明你申明的是全局变量,就需要 export对象 ,改变他的作用域。
同理可得,一个代码中,如果有export,import之类的代码,那么这个文件就会变成一个模块

  1. export {};
  2. let name:number = 123;

类型声明:
基本数据类型和原来一样;
数组有两种申明方式;
//元组的概念,元组类似于数组,它是一个长度和类型都固定的数组
//1.长度固定 2.类型可以不一样

  1. //在同一个作用域内部,相同的变量名 只能申明一次
  2. let name:number = 123;
  3. let b:string = "skjas";
  4. let c:string = "c";
  5. let nums:number[] = [1,2,3];
  6. let nums1:Array<Number> = [1,2,3];
  7. //元组的概念,元组类似于数组,它是一个长度和类型都固定的数组
  8. let point:[number,number] = [1,2];
  9. let person:[string,number] = ['1',2];
  10. //枚举类型,key的值是一个关联关系,可以指定任何value值,如果不指定,默认会给下标
  11. enum Gender {
  12. BOY = 1,
  13. GIRL = 2
  14. }
  15. //const 是常数枚举 ,会被编译成常量 ,不可更改
  16. const enum Color {
  17. Red,
  18. Yellow
  19. }
  20. console.log(Color.Red,Color.Yellow)
  21. //任意类型 any
  22. //引入了第三方库,没有进行类型定义, 类型转换的时候 ,数据结构太灵活的时候 用any
  23. //当使用 any 时 ,就是默认数据类型了
  24. let root: any = document.getElementById('root');
  25. //ts为所有的dom类型提供了一整套的类型申明
  26. let root: HTMLElement | null = document.getElementById('root');
  27. //断言
  28. //对象的! 表示开发者自己定义的 一定会保证存在的值 (断言不为空)
  29. //对象的? 表示如果有就赋值
  30. root!.style.color = 'red';
  31. // null空 undefined未定义
  32. //他们都是其他类型的子类型 你可以把它们赋值给其它类型的变量
  33. let myname: string|null = null;
  34. let myname1: string = undefined;
  35. //void类型 空的 (没有的意思)
  36. //void可以返回 null 和undefined
  37. function greeting(name: string): void {
  38. return null;
  39. //也可以不返回
  40. }
  41. //never 永远不
  42. //never 是其他类型的子类型,代表永远不会出现的值
  43. //在函数内部永远会抛出错误,导致函数无法正常结束
  44. function createError(message:string):never{
  45. console.log(1)
  46. throw new Error('error');
  47. console.log('end point')
  48. }
  49. function sum():never{
  50. while(true){
  51. console.log('123')
  52. }
  53. console.log('end point')
  54. }

never使用场景

1.启动一个后天任务,后台任务本身是监听,就是一个死循环,时间环函数,计划任务
2.写一些单元测试 的时候,就是让当前函数报出错误,看会不会影响别的函数

| , || 和 & ,&&的区别

| 是运算符中的 ,比如 let a = 3 | 5; a就等于 7 这个是二进制 加减
||就是 短路运算符,let a=3 || 5; a=3,
&也是运算中的,3&5 = 1
&& 短路运算符中的 let a=3 || 5; a=5,

ts类型推论

ts会根据你赋值的类型,推测出变量的类型,如果你申明的时候没有赋值,那么就会使 any

包装对象 java装箱和拆箱

//自动在基本类型的对象类型之间切换
1.基本类型上没有方法
2.在内部迅速完成一个装箱的操作,把基本类型迅速包装成对象类型,然后用对象来调用方法

  1. let name4:string ='asd';
  2. name4.toLocaleLowerCase(); //在运行到这里的时候,会自动把原来的string,变成包装对象。
  3. //然后就会可以使用 包装对象的方法

联合类型

就是可以同时申明两个类型 :let a : number | string

断言

不可以断言成没有申明的类型变量

  1. let a : number | string
  2. (a as string).toLocaleLowerCase();//断言 它是一个string ,然后就可以调用string的方法了
  3. (a as number).toFixed()它是一个number就可以调用number的方法

字面量类型

字面量类型 有点像枚举 ,申明后的值,赋值只可以是申明的这两个了
let Data: ‘Boy’ |’GIRL’;
Data=’Boy’;
Data=’GIRL’;

字面量类型和联合类型的比较

1.字符串字面量类型用来约束取值只能是某几个字符串中的一个,联合类型表示取值可以是多种类型中的一个
2.字符串字面量限定了使用过该字面量的地方,仅能接受特定的值,联合类型对于值没有限定,仅仅限定值的类型需要保持一致

函数

函数的定义
1.可以指定参数的类型和返回值的类型

  1. //函数定义
  2. function hello(name: string): void {
  3. console.log(name)
  4. return null;
  5. }
  6. //type用来定义一个类型 或者类型别名
  7. type GetUserNameType = (firstname: string, lastname: string) => string;
  8. //函数表达式
  9. let getUserName: GetUserNameType = (firstname: string, lastname: string): string => {
  10. return firstname + lastname;
  11. }
  12. //可选参数
  13. //? 代表的是可传可不传,没写问号的,就表示必须要传,调用的时候要么都传,要么都不传
  14. function print(name: string, age?: number, home?: string) {
  15. }
  16. //默认参数
  17. function ajax(url: string, method: string = 'GET') {
  18. console.log(method)
  19. }
  20. //剩余参数
  21. function sum(...number: Array<number>) {
  22. return number.reduce((accu, item) => accu + item, 0)
  23. }
  24. //函数重载
  25. //跟java一样接受参数类型不同表示重载
  26. //写了重载方法后,在调用的时候,传入别的类型就会报错
  27. //重载和函数之间不能有别的空格或者代码
  28. let obj:any={};
  29. function attr(val:string):void;
  30. function attr(val:number):void;
  31. function attr(val:any):void{
  32. }

  1. //如何定义类
  2. class Person {
  3. name: string = 'aa';
  4. age: number;
  5. constructor() {
  6. this.age = 10;
  7. }
  8. }
  9. let p1 = new Person();
  10. console.log(p1.name);
  11. console.log(p1.age);
  12. //存取器 getter setter
  13. namespace a {
  14. class Person {
  15. myName: string;
  16. constructor(name: string) {
  17. this.myName = name;
  18. }
  19. get name() {
  20. return this.myName;
  21. }
  22. set name(newValue: string) {
  23. this.myName = newValue.toLocaleUpperCase();
  24. }
  25. }
  26. let p = new Person('ass');
  27. console.log(p.name);
  28. p.name = 'jiagou';
  29. console.log(p.name);
  30. }
  31. //参数类型
  32. //public关键字指的是 ,把public申明的变量变成公开的,实例属性
  33. //相当于直接申明了 name:string ;
  34. namespace c {
  35. class Person {
  36. constructor(public name: string) {
  37. }
  38. }
  39. let p = new Person('ass');
  40. }
  41. //readonly
  42. //只能查看不能修改
  43. namespace b {
  44. class Person {
  45. constructor(public readonly name: string) {
  46. }
  47. }
  48. let p = new Person('ass');
  49. }
  50. //继承 ts跟设计模式相关
  51. /**
  52. * 子类继承父类后,子类的实例上,就拥有了父类中的属性和方法
  53. * 访问修饰符 public公开的 protected 受保护的 private私有的
  54. * public 自己 自己的子类和其他类都可以访问
  55. * protected 受保护的 自己和自己的子类可以访问,其他类不能访问
  56. * private 私有的只能自己访问,自己的子类不可以访问,其他类更不可以了
  57. */
  58. /**
  59. * static 静态属性 就是说不需要实例的属性,可以直接通过类名进行调用
  60. * 静态方法 同理
  61. * static申明的变量在 实例上, 平时申明的变量在原型(prototype)上
  62. */
  63. namespace d {
  64. class Person {
  65. public name: string;
  66. protected age: number;
  67. constructor(name: string, age: number) {
  68. this.name = name;
  69. this.age = age;
  70. }
  71. getName() {
  72. return this.name;
  73. }
  74. setName(newString: string) {
  75. this.name = newString
  76. }
  77. }
  78. class Student extends Person {
  79. stuNo: number;
  80. constructor(name: string, age: number, stuNo: number) {
  81. super(name, age);
  82. this.stuNo = stuNo;
  83. }
  84. }
  85. let stu = new Student("qwe", 123, 1);
  86. }

类装饰器

1.装饰器是一种特殊类型的申明,他能附加在类的申明、方法、属性或者参数上,可以修改类的行为
2.常见的装饰器有类装饰器,属性装饰器,方式装饰器和参数装饰器
3.装饰器的写法分为普通装饰器和装饰器工厂

  1. namespace a {
  2. // 接口
  3. interface Person {
  4. xx: string;
  5. yy: string;
  6. }
  7. //装饰器 接收参数 是类对象
  8. function enhancer(target: any) {
  9. target.prototype.name = "Person";
  10. }
  11. //装饰器放在class 类上
  12. @enhancer
  13. class Person {
  14. constructor() {
  15. }
  16. }
  17. let p = new Person();
  18. }
  19. //把类整个替换
  20. namespace b {
  21. //装饰器 接收参数 是类对象
  22. function enhancer() {
  23. return function (target: any) {
  24. return class extends Person {
  25. constructor(name: string, age: number) {
  26. super(name, age);
  27. }
  28. //返回的加强类
  29. getAge(){
  30. console.log(this.age);
  31. }
  32. }
  33. }
  34. }
  35. //装饰器放在class 类上 ,
  36. //这里的装饰器就变成了一个函数,去增强原来的类
  37. //注意 输出的 类要和原来的父类接收的类型一致
  38. @enhancer()
  39. class Person {
  40. name: string = 'persion';
  41. age:number = 10;
  42. constructor(name:string,age:number) {this.name=name;this.age=age }
  43. }
  44. let p = new Person('persion',10);
  45. console.log(p.age)
  46. }

属性装饰器

属性装饰器表达式会在运行时当作函数调用,传入下列参数
属性装饰器用来装饰属性
1.第一个参数对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
2.第二个参数是属性的名称

  1. //属性装饰器 装饰属性
  2. namespace c {
  3. //target如果装饰的是一个普通属性,target 指向类的原型 prototype
  4. //target装饰一个类属性static ,那么target指向类的定义
  5. //propertyName属性名
  6. function upperCase(target: any, propertyName: string) {
  7. let value = target[propertyName];
  8. const getter = () => value;
  9. const setter = (newVal: string) => {
  10. value = newVal.toUpperCase();
  11. }
  12. delete target[propertyName];
  13. Object.defineProperty(target, propertyName, {
  14. get: getter,
  15. set: setter,
  16. enumerable: true,
  17. configurable: true
  18. })
  19. }
  20. //属性装饰器工厂
  21. function propertyEnumerable(flag: boolean) {
  22. return function (target: any, propertyName: string) {
  23. }
  24. }
  25. //方法装饰器工厂,就是返回一个装饰器
  26. function mehtodEnumerable(flag: boolean) {
  27. /**
  28. * @target 指向实例或者原型
  29. * @methodName 方法的名称
  30. * @propertyDescriptor 属性描述器的值
  31. */
  32. return function (target: any, methodName: string, propertyDescriptor: PropertyDescriptor) {
  33. propertyDescriptor.enumerable = flag;
  34. }
  35. }
  36. //方法装饰器工厂,就是返回一个装饰器
  37. function setAge(age: number) {
  38. return function (target: any, methodName: string,) {
  39. target.age = age;
  40. }
  41. }
  42. function toNumber (target: any, methodName: string, propertyDescriptor: PropertyDescriptor){
  43. //取出老方法的值
  44. let oldMethod = propertyDescriptor.value;
  45. //老方法的值再去 转变格式
  46. propertyDescriptor.value= function(...args:any[]){
  47. //转变格式
  48. args=args.map(item=>parseFloat(item));
  49. //转变完成,调用 原来的方法
  50. return oldMethod.apply(this,args);
  51. }
  52. }
  53. class Person {
  54. static age: number;
  55. @upperCase
  56. name: string = "aa";
  57. age: number = 10;
  58. @mehtodEnumerable(true)
  59. getName() {
  60. console.log(1)
  61. }
  62. @setAge(100)
  63. static getAge() {
  64. }
  65. @toNumber
  66. sum(...args: any[]) {
  67. return args.reduce((accu, item) => accu + item, 0);
  68. }
  69. }
  70. let p = new Person();
  71. p.name = '架构';
  72. p.sum([1, '2', '3']) ////属性装饰器 装饰属性
  73. namespace c {
  74. //target如果装饰的是一个普通属性,target 指向类的原型 prototype
  75. //target装饰一个类属性static ,那么target指向类的定义
  76. //propertyName属性名
  77. function upperCase(target: any, propertyName: string) {
  78. let value = target[propertyName];
  79. const getter = () => value;
  80. const setter = (newVal: string) => {
  81. value = newVal.toUpperCase();
  82. }
  83. delete target[propertyName];
  84. Object.defineProperty(target, propertyName, {
  85. get: getter,
  86. set: setter,
  87. enumerable: true,
  88. configurable: true
  89. })
  90. }
  91. //属性装饰器工厂
  92. function propertyEnumerable(flag: boolean) {
  93. return function (target: any, propertyName: string) {
  94. }
  95. }
  96. //方法装饰器工厂,就是返回一个装饰器
  97. function mehtodEnumerable(flag: boolean) {
  98. /**
  99. * @target 指向实例或者原型
  100. * @methodName 方法的名称
  101. * @propertyDescriptor 属性描述器的值
  102. */
  103. return function (target: any, methodName: string, propertyDescriptor: PropertyDescriptor) {
  104. propertyDescriptor.enumerable = flag;
  105. }
  106. }
  107. //方法装饰器工厂,就是返回一个装饰器
  108. function setAge(age: number) {
  109. return function (target: any, methodName: string,) {
  110. target.age = age;
  111. }
  112. }
  113. function toNumber (target: any, methodName: string, propertyDescriptor: PropertyDescriptor){
  114. //取出老方法的值
  115. let oldMethod = propertyDescriptor.value;
  116. //老方法的值再去 转变格式
  117. propertyDescriptor.value= function(...args:any[]){
  118. //转变格式
  119. args=args.map(item=>parseFloat(item));
  120. //转变完成,调用 原来的方法
  121. return oldMethod.apply(this,args);
  122. }
  123. }
  124. class Person {
  125. static age: number;
  126. @upperCase
  127. name: string = "aa";
  128. age: number = 10;
  129. @mehtodEnumerable(true)
  130. getName() {
  131. console.log(1)
  132. }
  133. @setAge(100)
  134. static getAge() {
  135. }
  136. @toNumber
  137. sum(...args: any[]) {
  138. return args.reduce((accu, item) => accu + item, 0);
  139. }
  140. }
  141. let p = new Person();
  142. p.name = '架构';
  143. p.sum([1, '2', '3']) //这里原来调用输入 123 ,但是重新改了以后就输出6
  144. }
  145. }

参数装饰器

  1. //参数装饰器
  2. namespace d {
  3. //参数装饰 方法参数
  4. interface Person {
  5. age: number
  6. }
  7. //第一个参数 实例,第二个参数方法名,第三个参数,参数的索引
  8. function addAge(target: any, methodName: string, paramsIndex: number) {
  9. target.age = 10;
  10. }
  11. class Person {
  12. login(username: string, @addAge password: string) {
  13. console.log(this.age, username, password)
  14. }
  15. }
  16. let p = new Person();
  17. p.login('asd', "123")
  18. }

装饰器执行顺序

image.png
也就是 属性=》方法参数=》方法=》类
注意 :1.属性和方法 谁写在前面 谁就会先执行 ,最后才会是 类
2.同类型的,先执行后写的,然后依次向外

npm 配置源

装包的时候发现问题
1.当使用cnpm 和yarn 的装包时候,明明配置了源 。却访问到了npm 的源 ,然后报出 404的错误,
2.配置源地址的代码

  1. 一.通过命令配置
  2. 1. 命令
  3. npm config set registry https://registry.npm.taobao.org
  4. 2. 验证命令
  5. npm config get registry
  6. 如果返回https://registry.npm.taobao.org,说明镜像配置成功。
  7. 二、cnpm安装
  8. 1. 安装cnpm
  9. npm install -g cnpm --registry=https://registry.npm.taobao.org
  10. 2. 使用cnpm
  11. cnpm install xxx