typescript

  目录:

  一、环境配置

  二、ts的类型

  三、ts中的函数

  四、ts中的接口定义

  五、ts中的泛型

  六、ts中的命名空间

  七、ts中的装饰器

环境配置

  1、全局安装typescript:npm i -g typescript

  2、在cmd中进入到ts文件夹内,运行tsc --init,创建tsconfig.json文件,修改文件里的outDir选项(生成的js文件的地址)

  3、在vsCode中选择终端->运行任务->监视tsconfig.json,ts文件变化时会自动生成对应的js文件

typesrcipt类型:

1、分类:布尔类型:boolean、数字类型:number、字符串类型:string、数组类型:array、元组类型:tuple、枚举类型enmu、任意类型:any、undefined和null、void类型、never类型

 2、语法:变量名:类型 = 赋值

let b: boolean = true;
// b = "ss";  //赋值其他类型的值时会报错
let s: string = "string";
let n: number = 2;
console.log(b, s, n);

//数组类型
let arr: number[] = [1, 2];
let arr1: Array<number> = [1, 2]; //第二种写法

//元组类型:是array类型中的一种,给每一个元素指定一个类型
let t: [number, string] = [1, "1"]; //必须一一对应
let t1: any[] = [1, "s", true]; //元素可以为任意类型
console.log(arr, t);

//枚举类型,如果不给元素赋值则它的值为对应的下标(下标从0开始),如果某项赋值了,并且为整数,则其后面的选项会在此值上累加,如果是非整数,则其后面的元素必须赋值,否则会报错
enum Color {
  blue,
  green = 3,
  red
}
//enum Color {blue,green='green',red};    //报错
let bc: Color = Color.blue;
let gc: Color = Color.green;
let rc: Color = Color.red;
console.log(bc);
console.log(gc);
console.log(rc); //green的值被初始化为3,则red对应累加,变成4

//any类型,相当于放弃了ts的类型检查,可以随意转化类型
var a: any = { a: "aa" };
a = "sss";
console.log(a);

//undefined和null,定义变量但未赋值时使用,可以给一个变量设置多个类型
var n: number | undefined | null; //num可能为number类型,可能是undefined,也可能是null
n = 22;
console.log(n);

//void类型:表示没有任何类型,一般用于没有返回值的方法
function voidFn(): void {
  console.log("voidFn");
}
voidFn();

ts中的函数

1、指定参数的类型,可以设置默认值,可以设置是否可选

 2、指定返回值的类型

function run(name: string, age: number): string {
  return name + ":" + age + "岁";
}
console.log(run("张三", 22));

//使用?来设置是否可选,可选参数必须放置在必选参数之后
function run(age: number, name?: string): string {
  return name ? name + age : "陌生人" + age;
}
console.log(run(20, "张三")); //张三
console.log(run(20)); //陌生人

//设置默认值
function run(name: string = "默认名字"): string {
  return name;
}
console.log(run("张三")); //张三
console.log(run()); //默认名字

ts中的接口定义:使用interface关键字

1、接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法

 2、属性类接口

 3、函数类型接口

 4、类类型接口

 5、接口的继承

//属性类接口
//iPerson接口必须有name(string类型)属性,可以有age(number类型)属性
interface iPerson {
  name: string;
  age?: number;
}
let person: iPerson = {
  name: "张三",
  age: 20
  // sex: "man"     //报错,接口中没有sex属性
};
console.log(person);
//TIPS:如果不能确定最后的传参是否比接口有更多的参数,可以使用'字符串索引签名'([propName: string])来绕开多余参数的检查
interface iPerson {
  name: string;
  age?: number;
  [propName: string]: any;    //定义了属性名为string类型,属性值为any类型
}
let person: iPerson = {
  name: "张三",
  age: 20,
  sex: "man"     //使用了字符串索引签名,不会报错
};
console.log(person);

//函数类型接口
// iFn接口定义了参数和返回值规范
interface iFn {
  (name: string, age?: number): string;
}
let man: iFn = function(name: string, age?: number): string {
  let n = "man" + name;
  return age ? n + age : n;
};
let woman: iFn = function(name: string, age?: number): string {
  let n = "woman" + name;
  return age ? n + age : n;
};
console.log(man("张三"));
console.log(woman("韩梅梅"));

//类类型接口,约束类的属性和方法
//定义了iPerson接口,必须包含name、age属性和setAge方法
interface iPerson {
  name: string;
  age: number | undefined;
  setAge(age: number): void;
}
//使用关键字implements,Person类必须满足iPerson接口的格式
class Person implements iPerson {
  name: string;
  age: number | undefined; //未在初始化时给age赋值,所以age的类型需要加上undefined
  constructor(name: string) {
    this.name = name;
  }
  setAge(age: number) {
    this.age = age;
  }
}
let p = new Person("张三");
p.setAge(20);
console.log(p);

//接口的继承,使用extends关键字
interface iPerson {
  name: string;
}
interface iMan extends iPerson {
  sex: string;
}
let m: iMan = {
  name: "张三",
  sex: "man"
};
console.log(m);

ts中的泛型,使用<>来定义泛型

1、当没有办法确定数据类型时,除了用any(any相当于放弃了数据类型检查),还可以使用泛型。泛型就是解决对不确定数据类型的支持,在调用时才确定数据类型

  2、方法中的泛型

  3、类中的泛型

  4、接口中的泛型

  5、作为参数的泛型类

//方法中的泛型,在调用时才确定T的类型
//test方法,规定了传入的参数和函数返回值都是T的类型
function test<T>(value: T): T {
  return value;
}
console.log(test<number>(20)); //T为number类型,则传入的值和返回值也要为number类型
console.log(test<string>("s")); //T为string类型
// test<number>('s');    //错误,传入的值不是number类型

//类中的泛型,在创建Test实例时确定T的数据类型
class Person<T> {
  names: T[] = [];
  add(value: T): void {
    this.names.push(value);
  }
}

var p = new Person<string>(); //规定了T为string类型,则Person类中所有的T都要为string类型
p.add("张三");
p.add("李四");
p.add("韩梅梅");
console.log(p);

//在接口中的泛型
interface iPerson<T> {
  name: string;
  data: T;
}
interface iBaseInfo {
  age: number;
  sex: string;
}

let p: iPerson<iBaseInfo> = {
  //泛型T的类型为iBaseInfo,因此data的数据结构必须符合接口iBaseInfo的结构
  name: "张三",
  data: {
    age: 20,
    sex: "man"
  }
};
console.log(p);

//作为参数的泛型类
class User {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
class People<T> {
  list: T[] = [];
  add(p: T): void {
    this.list.push(p);
  }
}
let p = new People<User>(); //把user类作为参数传给People类,People的泛型为user,所以add传的参数只能是User类型
let u = new User("张三", 20);
p.add(u);
console.log(p);

ts中的命名空间

1、使用namespace关键字定义命名空间

2、命名空间内的变量是私有的,如果要访问,需要使用export导出

namespace nPerson {
  interface iN {
    name: string;
  }
  export class People {
    name: iN;
    constructor(name: iN) {
      this.name = name;
    }
  }
}
var p = new nPerson.People({ name: "张三" });
console.log(p);

ts中的装饰器,使用@使用装饰器,装饰器必须放在被装饰的前面,并且不能加分号

  1、装饰器是一种特殊类型的声明,它能够被附加到类声明、方法、属性、参数上,以此改变他们的行为。通俗地讲,装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展他们的功能。

  2、装饰器的分类:普通装饰器(无法传参),装饰器工厂(可传参,一般使用这种)

  3、类装饰器

  4、属性装饰器

  5、方法装饰器

  6、参数装饰器

//类装饰器:类装饰器在类声明之前被声明(紧挨着类声明),类装饰器应用于类构造函数,可以在不修改类的前提下拓展类的功能
function logClass(param: string) {
  return function(target: any) {
    //target指向类
    //拓展属性
    target.prototype.sex = param;
    //拓展方法
    target.prototype.getSex = function() {
      console.log(this.sex);
    };
  };
}

//属性装饰器:属性装饰器表达式会在运行时当做函数被调用,传入2个参数:1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象,2、属性名
function logProperty(param: number) {
  return function(target: any, attr: any) {
    target[attr] = param; //修改了target下的attr属性的值
  };
}

//方法装饰器:它会被应用到方法的属性描述符上,可以用来监视、修改、替换方法定义,传入3个参数:1、对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象。2、方法名。3、成员的属性描述
function logMethod(param?: any) {
  return function(target: any, name: string, desc: any) {
    //修改原方法
    var oMethod = desc.value;
    desc.value = function(...args: any[]) {
      console.log(param);
      return oMethod.apply(this, args); //继续执行原方法里的代码
    };
  };
}

//参数装饰器:参数装饰器表达式会在运行时当做函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入3个参数:1、对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象。2、方法的名字。3、参数在函数参数列表中的索引位置。
function logParam(param?: any) {
  return function(target: any, methodName: string, paramIndex: number) {
    console.log("logParam:::", target);
    console.log("logParam:::", methodName);
    console.log("logParam:::", paramIndex);
  };
}

@logClass("man")
class People {
  @logProperty(22)
  age: number | undefined;
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  @logMethod("方法装饰器")
  getName(): string {
    return this.name;
  }
  setName(@logParam("获取参数") name: string) {
    this.name = name;
  }
}
let p: any = new People("张三"); //变量p需定义为any类型,否则获取装饰器里的属性和方法时会报错
console.log(p.age);
p.getSex();
console.log(p.getName()); //p.getName()的值为方法修饰器方法里返回的值
p.setName("李四");
console.log(p.name);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值