TypeScript——接口(对象接口)、函数(定义类型,可选参数,默认参数,剩余参数,函数类型变量,函数接口)

一、接口

TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。

1、对象接口

用接口来约束参数的类型结构(对象的形状):

  1. 约定对象的成员数量及类型要求

  2. 只关注值的外形, 只要传入的对象满足提到的条件,那么它就是被允许的。

  3. 对象是无序的:类型检查器不会检查属性的顺序,只要相应的属性存在且类型是对的就行。

  4. 使用接口必须实现里面的必实现项    

interface dog{
    age: number;
    name: string;
}
let d1:dog
d1={
    age:1,
    name:"小黑",
}
//d1对象必须实现age和name属性

2、可选属性

  1. 接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。
  2. 可选属性在应用“option bags”模式时很常用,即给函数传入的参数对象中只有部分属性赋值。
  3. 带有可选属性的接口与普通的接口定义差不多,在可选属性名字定义的后面加一个?符号。

  使用好处:

  • 可以对可能存在的属性进行预定义;
  • 可以捕获引用了不存在的属性(往往是无意之中敲错的代码)时的错误;

注意:可选属性可以不实现,但是一旦实现就必须是声明时的类型

interface dog{
    age: number;
    name: string;
    color?:string  //可选实现 但是实现就必须是string类型的
}
let d1:dog
d1={
    age:1,
    name:"小黑",
    color:"black" , //可写可不写,写了就必须是string类型 否则编译报错
}

3、只读属性

一些对象属性只能在对象刚创建的时候修改其值。 可以在属性名前用 readonly来指定只读属性。

readonly vs const:做为变量使用的话用 const,若做为属性则使用readonly。

注:TypeScript具有ReadonlyArray<T>类型,它与Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改。

interface dog{
    age: number;
    name: string;
    readonly position:string;   //只读属性 不可以修改
}
let d1:dog
d1={
    age:1,
    name:"wang",
    position:"fixed"
}
d1.age=2   //可以修改
d1.position="absulute"   //不可以修改:无法分配到 "position" ,因为它是只读属性

二、函数

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

1、为函数定义类型

   声明式:作用域中直接声明一个函数

function fn(n1: number, n2: any[], n3: Array<string>): number {
    return 100  //隐式也能推论出返回值是number 但尽量自己加上函数的返回值类型
}
let result: number = fn(100, [20, true], ["haha"])
console.log(result)

   定义式:当做数据引用

let a = function ():void { };
let obj = { fn: function () :void{ } };
let arr = [function ():void { }];
(function (n:number):number { return n*2})(100)

  我们可以给每个参数添加类型之后再为函数本身添加返回值类型。 TypeScript能够根据返回语句 自动推断出返回值类型,因此我们通常省略它,但尽量不要省略。

 小练习:

定义一个返回值为元组的函数:

function fm(n1:number,n2:string):[number,string]{

    return [n1*2,n2]

}

期望再多返回一个数字 : 元组中加一个类型

function fm1(n1:number,n2:string):[number,string,number]{

    return [n1*2,n2,100]

}

期望再多返回一个数字 : 元组改为数组

function fm2(n1:number,n2:string):any[]{

    return [n1*2,n2,100]

}

2、可选参数和默认参数

传递给一个函数的参数个数必须与函数期望的参数个数一致。

function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}
​
let result1 = buildName("haha");                  // 错误,参数不够
let result2 = buildName("haha", "xixi", "yoyo");  // 错误,超出参数个数
let result3 = buildName("haha", "xixi");         // 正确,与参数个数一致

在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。

注:可选参数必须跟在必选参数后面

function fun(n1:number,n2?:string|undefined):Array<number|string>{
    return [n1*2,n2,100]  //严格模式下不能将undefined赋值给其他类型,非严格模式可以
}
fun(100)       //n2是可选参数,可以传参,也可以不传参,不会报错
fun(100,"haha")  

还可以给参数设置默认值,在所有必选参数后面带默认值的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。

function fun1(n2?:string,n1:number=100){
    //n1就是可选默认 虽然没有写? 但是只有可选参数才有默认值
}
fun1() //n1,n2都是可选参数,所以此处不传参

注:带默认值的参数不需要放在必选参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入 undefined值从而来获得默认值。

3、剩余参数

  在js里面叫rest参数 ...restArr

function rest(n1:number,n2:string,...arg){
    console.log(arg)  //1,true
}
rest(10,"haha",1,true)
//对rest进行类型约束
function rest1(n1:number,n2:string,...arg:[number,string]){
    console.log(arg)  //[1,"haha"]
}
rest1(10,"haha",1,"haha")  //剩余参数类型是元组 只能传两个且为numer和string

function fg(n1:number,n2:string,...rest:[number,string]):[any[],Array<number>]{
return [[10,20,true],[10,20]]
}
fg(100,"haha",10,"xixi")

4、函数类型变量

声明函数类型时用" => "," => "后必须写函数返回值类型  无返回值为空时也必须写void

  1. 变量的类型可以声明为函数类型:

    let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; };
    //这里的 => 不是箭头函数,而是表示在声明函数的类型
  2. 函数类型属于自定义类型,包含两部分:参数类型和返回值类型:

    //声明一个变量并指定类型为自定义的函数类型
    let myadd:(x:number, y:number)=>number;
    //声明一个函数
    function add(x: number, y: number): number {
        return x + y;
    }
    //把函数赋值给类型为函数类型的变量
    myadd = add;
    ​
    //赋值匿名函数
    myadd =  function(x: number, y: number): number {
        return x + y;
    }
    //赋值箭头函数
    myadd =  (x: number, y: number):number=>{
        return x + y;
    }
  3. 只要参数类型是匹配的,那么就认为它是有效的函数类型,并不要求参数名一样,很多时候参数名是为了增加可读性

    let myAdd: (baseValue: number, increment: number) => number =
        function(x: number, y: number): number { return x + y; };
  4. 在函数和返回值类型之前使用( =>)符号,返回值类型是函数类型的必要部分,如果函数没有返回任何值,你也必须指定返回值类型为 void而不能留空。

5、使用接口封装函数变量类型

自定函数类型代码往往很长,可以使用接口来封装该类型,之后使用接口来代表该类型

interface myfun1{

    //函数格式:

    ():number

}

let my1:myfun1    //myfun1接口代表my1类型的函数

my1=():number=>{return 100}

interface myfun2{

    //函数格式:

    (number,string):number

}

let my2:myfun2     //myfun2接口代表my2类型的函数

my2=function(arg1:number,arg2:string):number{return 111}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈ha~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值