typescript 学习笔记1

124 阅读5分钟

1. typescript是什么

Typescript是由微软开发的一款开源的编程语言 Typescript是Javascript的超集,遵循最新的ES5/ES6规范。TypeScript扩展了Javascript语法 TypeScript更像后端Java、C#这样的面向对象语言可以让JS开发大型企业应用 越来越多的项目是基于TS的,比如VSCode、Angular6、Vue3、React16 TS提供的类型系统可以帮助我们在写代码的时候提供更丰富的语法提示 在创建前的编译阶段经过类型系统的检查,就可以避免很多线上的错误

#2. TypeScript安装和编译

cnpm i typescript -g tsc helloworld.ts // 安装依赖 tsc --init // 生成配置文件 tsc // 执行编译 使用export 或者import ts会将当前所在文件变成一个模块

3基本数据类型

boolean、number、string、array、null 、undefined tuple(元祖类型):表示一个已知数量和类型的数组 enum(枚举类型) any(任意类型) void : 表示没有任何类型 never:代表不会出现的值类型 Symbol:值是唯一不变的的类型 BigInt:大整型,大于2*53-1的数字时,就可以用他

4 复杂数据类型

4.1函数

可以指定参数的类型和返回值的类型

4.1.1函数重载

在Java中的重载,指的是两个或者两个以上的同名函数,参数不一样 在TypeScript中,表现为给同一个函数提供多个函数类型定义

	function add(a: string, b: string):void
	function add(a: number, b: number):void
	function add(a: string|number, b: string|number):void {
		 a+b
	}
	add('a', 'b')
	add(1, 2)
	add(1,'b') // 如指定为ab都为数字或者都为string时,这种就能检测出错

4.2类

类class的类型 本质上是一个函数; 类本身就指向自己的构造函数。

	// 当我们写一个类的时候,会得到2个类型 1. 构造函数类型的函数类型2. 类的实例类型
	class Component {
		static myName: string = '静态名称属性';
		myName: string = '实例名称属性';
	}
	let com = Component;
	//Component类名本身表示的是实例的类型
	let c: Component = new Component();
	let f: typeof Component = com;
	 
	//
	//
	//类Component转义成es5的js就是这样的
	var Component = /** @class */ (function () {
		function Component() {
			this.myName = '实例名称属性';
		}
		Component.myName = '静态名称属性';
		return Component;
	}());

4.2.1 类的修饰符

public 自己,自己子类和其他类都能访问 protected 其他类不能访问 private 子类和其他类不能访问

4.2.1 类的装饰器

一种特殊的声明,可以被附加类、方法、属性上,还可以分为普通装饰器和装饰器工厂

4.2.1.1类装饰器

在类声明之前声明,用来监视、修改或替换类定义

	/**
	 * @param {type} x: 是这个类的构造函数 
	 */
	function addName(x: Function) {
		x.prototype.name = 'aa'
		x.prototype.eat = function () {
			console.log('aaaa');
		}
	}
	@addName
	// addNameFactory('哈哈')
	class Person {
		name!: string;
		eat!: Function;
		constructor() { }
	}
	/**
	 * 装饰器工厂,工厂模式
	 * @param {type} x: 是这个类的构造函数 
	 */
	// function addNameFactory(name: string) {
	//   return function addName(x: Function) {
	//     x.prototype.name = 'aa'
	//     x.prototype.eat = function () {}
	//   }
	// }

4.2.1.2 属性装饰器

装饰实例属性时,装饰器入参为: (target:是当前类的构造函数的原型,key: 属性key名)

装饰静态属性时,装饰器入参为: (target:是当前类的构造函数本身,key: 属性key名)

装饰实例方法时,装饰器入参为: (target:是当前类的构造函数本身,key: 方法key名,desc: PropertyDescriptor也叫属性描述器)

4.2.1.3 参数装饰器

装饰静态参数时, 装饰器入参为: (target:是当前类的构造函数本身,methodName: 方法名称,paramIndex: 参数索引)

装饰非静态参数时, 装饰器入参为: (target:是当前类的构造函数的原型,。。。同上)

4.2.1.4 装饰器执行顺序

所有装饰器的执行顺序一般是:先上后下,先内后外

从内往外执行,先内后外,先执行方法的参数,再执行方法,先执行属性方法,后执行类。 从上往下执行,先上后下。

4.2.2 抽象类

抽象描述一种抽象的概念,无法被实例化,只能被继承,抽象方法不能在抽象类中实现,只能在抽象类的具体子类中国年实现,且必须实现

	abstract class Animal { abstract spack():void } 
	class Dog extends Animal {abstract spack():void {console.log('汪汪')} }
	class Pig extends Animal {abstract spack():void {console.log('哼哼')} }

子类才可以实例化,且抽象类中的抽象方法必须重写,实现继承和多态

4.3接口

一方面可以在面向对象编程中表示为行为的抽象,另外可以用来描述对象的形状 吧一些类中国年公用的属性和方法抽象出来,用来约束实现此接口的类 一个类可以继承另一个类并实现多个接口,一个接口可以继承另一个接口, 接口可以同名,同名的类型会自动合并

4.3.1 函数类型接口

interface Fun { (name:string):any };
let fu:Fun = (name:steing) => {}

4.3.1 可索引接口

interface User { [index:number]: string };
let user: User = { 0:'a', }

4.3.1 描述类的构造函数接口

interface OneClass  { new(name:string):any };
class Comp { desc: string = '战神' }
let one: OneClass = Comp;

4.3.1 接口和抽象类的区别

  • 抽象类的抽象方法必须在子类中被实现
  • 抽象类能够实现方法和初始化属性,而接口仅能用户描述,不能提供方法的实现和属性粗话实话

4.4 泛型

定义一个宽泛的类型,通常用于类、函数、接口,将这个类型作为一个特殊参数传入,在类/函数中使用这个T类型,最后在实例化的时候可以具体定义T的类型

    //函数泛型
   function createAry(length:number,value:T):Array {
   	let res:T[] = [];
     for(let i = 0,i< length; i++) {
   	res[i] = value
     }
     return res
   }
   let demonAry = createAry(3,'x');
   let demonAry1 = createAry(3,5);

   // 泛型类
   class MyAry {
   	private list: T[] = []
     add(value:T) {
   	this.list.push(value);
     }
   }
   let ary = new MyAry();
   ary.add(1);
   ary.add(2);
   console.log(ary)

   // 泛型接口
   interface Calculate{
   	(a:T,b:T):T
   }
   let sum: Calculate = function(a:T,b:T):T {
   	return a
   }

4.4.1 默认泛型,可以设置默认值

function createAry(length:number,value:T):Array {}

4.4.2 泛型约束1

判断是否满足对应属性的约束条件,接口和对象属性上的条件只能多不能少

	interface LengthWise {
		length:number
	}
	function Logger<T extends LengthWise>(val: T) {
		console.log(val.length)
	}
	logger<string>('sss') // 这是对的,因为string类型有length
	logger<number>(1) // 这是错的,number类型没有length

4.4.3 泛型约束2

对于联合类型可以少不能多

   interface Cal { (a:T, b:T):void }
   let temp: Cal = function(a:T, b:T):void {}
   temp('a','a') // 是对的
   temp('a','a') // 是错的,联合类型只能取子类型