typescript学习(二)

这里记录下Typescript第二部分的学习,重点注意下接口以及函数’

四 接口

1.接口的基本使用

  • 什么是接口?

    接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,

    然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法

  • 格式:

interface interface_name {}

type 名称 = {}

/* 
接口是什么?
  接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,
  然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法 

  接口也是一种数据类型

格式:
  interface interface_name { 
  }
*/

interface IFullName {
  firstName: string
  lastName : string
}

let goddassName: IFullName = {
  firstName: "邱",
  lastName: "淑贞"
}

console.log(goddassName.firstName);
console.log(goddassName.lastName);



function say({firstName, lastName}:IFullName):void {
  console.log(`我的姓名是:${firstName}_${lastName}`);
}
say(goddassName);

2.可选属性与只读属性

  • 可选属性使用: ?
  • 只读属性使用: readonly
  • readonly与const的区别: 做为变量使用的话用 const,若做为属性则使用readonly
export default {}


// 可选属性   使用?来进行修饰
interface IFullName {
  firstName: string
  lastName : string
  age?: number
}

let goddassName: IFullName = {
  firstName: "邱",
  lastName: "淑贞"
}

console.log(goddassName.firstName);
console.log(goddassName.lastName);


// 只读属性  readonly
interface IInfo {
  readonly uname: string;
  readonly uage: number;
}

let beauty:IInfo = {
  uname: "邱淑贞",
  uage: 18
}

// beauty.uname = "赵丽颖";  // 报错

/* 
  总结: readyonly 与 const 区别:
    最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 
    做为变量使用的话用 const,
    若做为属性则使用readonly
*/

3.索引签名

  • 定义: 索引签名用于描述那些“通过索引得到”的类型
  • 格式: 如[props: string]:any
  • 应用场景: 解决参数问题

当需要传入的参数多个且不确定的时候需要(疑问,为什么不用any,当传入且不确定any不是更好

4.函数接口

  • 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。

​ 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。

export default {}

// 函数接口
/* 
  为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 
  它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型
*/

interface ImakeMoney {
  (salary:number, reward:number):number
}


let sum:ImakeMoney = function (x:number, y:number):number {
  return x + y;
}
let res = sum(10, 20);
console.log(res);


// 接口与数组
// 我们定义了StringArray接口,它具有索引签名。 
// 这个索引签名表示了当用 number去索引StringArray时会得到string类型的返回值
interface IStringArray {
  [index: number]: string;
}

let myArray: IStringArray;
myArray = ["邱淑贞", "赵今麦"];

let myStr: string = myArray[1];
console.log(myStr);

可以通过实现函数的方式来实现函数接口,这里还演示了通过标注未number的方式可以拿到索引的下标

5.接口的继承

接口继承就是说接口可以通过其他接口来扩展自己。

  • Typescript 允许接口继承多个接口。
  • 继承使用关键字 extends。
// 单继承
interface IPerson { 
  age:number 
} 
interface IName extends IPerson { 
  name:string 
} 

let lady:IName = {
  name: "邱淑贞",
  age: 18
}

// 多继承
interface IFatherMoney {
  m1: number
}
interface IMotherMoney {
  m2: number
}

interface ISon extends IFatherMoney, IMotherMoney {
  s: number
} 

let money:ISon = {
  m1: 100,
  m2: 100,
  s: 100
}


console.log(`儿子一共有${money.m1 + money.m2 + money.s}万元`);

6.接口的混合类型

比较一下接口和别名的区别

先不要看默认比较一下两者的共同点和不同点。
一、两者都可以实现类似于限定类型的效果。
Type别名是

export default {}

// 第一种
type beautys = "邱淑贞" | "赵雅芝" | "王祖贤" | "朱茵"
let one:beautys;

one = "邱淑贞";
// one = 100 // 报错


// 第二种
type myfun = (a:number, b:number) => number;

let fun:myfun = (a:number, b:number) => a + b;
fun(10, 20);


// 第三种
type myGoddass = {
  name: string,
  age: number,
  sex: string,
  actor?: boolean
}

let shuzhen:myGoddass = {
  name: "邱淑贞",
  age: 18,
  sex: "女"
}

而接口的基本使用类似于这样

/* 
接口是什么?
  接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,
  然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法 

  接口也是一种数据类型

格式:
  interface interface_name { 
  }
*/

interface IFullName {
  firstName: string
  lastName : string
}

let goddassName: IFullName = {
  firstName: "邱",
  lastName: "淑贞"
}

console.log(goddassName.firstName);
console.log(goddassName.lastName);



function say({firstName, lastName}:IFullName):void {
  console.log(`我的姓名是:${firstName}_${lastName}`);
}
say(goddassName);

两者的异同
都可以通过类似规定类型的方式来实现,但是接口似乎更灵活一些

1.相同点:

  • 都可以描述属性或方法
  • 都允许拓展

2.不同点:

  • type可以声明基本数据类型,联合类型,数组等; interface只能声明变量
  • 当出现使用type和interface声明同名的数据时;type会直接报错;interface会进行组合
  • type不会自动合并;interface会
// 相同点:
// 1.都可以描述属性或方法
type womenStar = {
  name: string
  age: number
  perform(): any
}
interface IWStar {
  name: string
  age: number
  perform(): any
}

let star1 = {
  name: "邱淑贞",
  age: 18,
  perform() {
    return "倚天屠龙记"
  }
}
let star2 = {
  name: "李一桐",
  age: 18,
  perform() {
    return "射雕英雄传"
  }
}

// 2.都允许拓展
type money  = {
  y1: number
}
type money2 = money & {
  y2: number
}

let salary:money2 = {
  y1: 10,
  y2: 20
}

interface Istar1 {
  name: string
}
interface Istar2 extends Istar1 {
  age: number
}

let starInfo:Istar2 = {
  name: "邱淑贞",
  age: 18
}


// 不同点:
// 1.type可以声明基本数据类型,联合类型,数组等
//   interface只能声明变量
type age = number;
type info = string | number | boolean;
type beautyList = [string | number];
// interface Iage = number; // 报错


// 2.当出现使用type和interface声明同名的数据时
//   type会直接报错
//   interface会进行组合
// type mygoddassName = {
//   name: string
// }

// type mygoddassName = {
//   name: number
// }

interface mygoddassName {
  name: string
} 
interface mygoddassName {
  name: string
  age: number
} 

let goddass:mygoddassName = {
  name: "赵丽颖",
  age: 20
}

五、函数

1.函数的基本使用

  • 介绍

    函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为的地方。 TypeScript为JavaScript函数添加了额外的功能,让我们可以更容易地使用

export default {}

// 匿名函数
const makeMoney = function(salary: number, reward: number): number {
  return salary + reward
}


// 有名函数 | 命名函数 | 普通函数
function writeCode(hour: number, sleep: number) {
  return hour
}
 

// 箭头函数
const seeMeiMei = (time: number):void => {
  console.log(`我每天要看${time}个小时MeiMei`);
  
}

seeMeiMei(8)


// 接口函数
type myFunc = (x: number, y: number) => number

const myfunc:myFunc = (a: number, b: number) => a + b

2.函数参数的处理

  • 可选参数:
    在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号标识 `?
  • 默认参数:
    我们也可以设置参数的默认值,这样在调用函数的时候,如果不传入该参数的值,则使用默认参数,语法格式为 ```
function function_name(param1[:type],param2[:type] = default_value) { 
}

剩余参数:

有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义。

剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。...args:any[]

// 可选参数
const func1:(x: number, y?: number)=>number = function(a, b) {
    return a;
  }
  
  
  const func2 = function(a: number, b?: number): number {
    return a;
  }
  
  func2(10);
  func2(10, 20);
  func2(10, undefined);
  
  
  // 函数的默认值
  const func3 = function(a: number = 1, b:number =2, c:number=3) {
    return a + b + c;
  }
  
  func3();
  func3(10);
  func3(10, 20);
  func3(10, 20, 30);
  
  
  // 函数的剩余参数
  const func4 = function(...args:any[]) {
    console.log(args);
    
  }
  
  func4(10, 20 , 30, "邱淑贞");
  
  const func5 = function(a:number, b:number, ...args:any[]) {
    console.log(a);
    console.log(b);
    console.log(args);
    
  }
  
  func5(10, 20 , 30, "邱淑贞", "邢菲");

3.构造函数

TypeScript 也支持使用 JavaScript 内置的构造函数 Function() 来定义函数:

语法格式如下:

var res = new Function ([arg1[, arg2[, ...argN]],] functionBody)

参数说明:

  • arg1, arg2, … argN:参数列表
  • functionBody:一个含有包括函数定义的 JavaScript 语句的字符串。

4.函数重载

重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

参数类型不同:

function disp(string):void;
function disp(number):void;

参数数量不同:

function disp(n1:number):void;
function disp(x:number,y:number):void;

参数类型顺序不同:

function disp(n1:number,s1:string):void;
function disp(s:string,n:number):void;

如果参数类型不同,则参数类型应设置为 any

参数数量不同你可以将不同的参数设置为可选。


// 不使用函数重载的问题
function add(a: number, b: number){
  return a + b;
}

add(10, 20);


function add2(a: string, b: string){
  return a + b;
}

add2("我的女神是: ", "邱淑贞");



function add3(a: string| number, b: string | number){
  // return a + b;
  if( typeof a=="number" && typeof b=="number"){
    return a + b;
  }
  if( typeof a=="string" && typeof b=="string"){
    return a + b;
  }
  if( typeof a=="string" && typeof b=="number"){
    return a + b;
  }
  if( typeof a=="number" && typeof b=="string"){
    return a + b;
  }
}

add3("我的女神是: ", "邱淑贞");
add3(10, 20);
add3("邱淑贞", 20);


// 定义函数重载
function addFunc(a:number, b: number):number;
function addFunc(a:string, b: string):string;
function addFunc(a:number, b: string):string;
function addFunc(a:string, b: number):string;


// 使用函数重载
function addFunc(a: any, b: any):any {
  return a + b;
}
addFunc(10, 20);
addFunc("谭松韵", "金晨");
addFunc(27, "白鹿");
addFunc("赵今麦", 19);


// 定义参数类型与参数数量不同
function star(s1:string):void; 
function star(n1:number,s1:string):void; 
 
function star(x:any,y?:any):void { 
    console.log(x); 
    console.log(y); 
} 
star("王心凌"); 
star(1,"爱你");

5.this的使用

  • JavaScript里,this的值在函数被调用的时候才会指定。 这是个既强大又灵活的特点,但是你需要花点时间弄清楚函数调用的上下文是什么。 但众所周知,这不是一件很简单的事,尤其是在返回一个函数或将函数当做参数传递的时候。

  • 从 TypeScript 2.0 开始,在函数和方法中我们可以声明 this 的类型,实际使用起来也很简单

  • 使用this参数,改变指向

  • 传入this参数,禁止调用this

let userInfo = {
  name: "邱淑贞",
  age: 18,
  song: "恨你太无情",
  marry: true,
  show: function () {
    this.marry = false;
  },
};



class Rectangle1 {
  private w: number;
  private h: number;

  constructor(w: number, h: number) {
    this.w = w;
    this.h = h;
  }

  getArea() {
    return () => {
      return this.w * this.h;
    };
  }
}

class Rectangle2 {
  private w: number;
  private h: number;

  constructor(w: number, h: number) {
    this.w = w;
    this.h = h;
  }

  getArea(this: Rectangle2) {
    return () => {
      return this.w * this.h;
    };
  }
}

// class Rectangle3 {
//   private w: number;
//   private h: number;

//   constructor(w: number, h: number) {
//     this.w = w;
//     this.h = h;
//   }

//   getArea(this: void) {
//     return () => {
//       return this.w * this.h;
//     };
//   }
// }

6.特殊的函数返回值

  • 如果使用类型别名,定义了一个返回值为void的类型, 我们在函数使用的时候,并非一定不能有返回值。

    相反,如果我们在函数中写了返回值,我们的返回值是有效的。

  • 如果我们定义函数的时候明确指出,返回值为void,那么我们将除undefined 和 null 以外的值进行返回都会进行报错


}

let f1 = func1();
let f2 = func2();
console.log("f1: ", f1);
console.log("f2: ", f2);



// 注意点: 如果我们定义函数的时候明确指出,返回值为void,
// 那么我们将除undefined 和 null 以外的值进行返回


function func3():void {
  // return 123 // 报错
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值