TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
用接口来约束参数的类型结构(对象的形状):
约定对象的成员数量及类型要求
只关注值的外形, 只要传入的对象满足提到的条件,那么它就是被允许的。
对象是无序的:类型检查器不会检查属性的顺序,只要相应的属性存在且类型是对的就行。
使用接口必须实现里面的必实现项
- interface dog{
- age: number;
- name: string;
- }
- let d1:dog
- d1={
- age:1,
- name:"小黑",
- }
- //d1对象必须实现age和name属性
?符号。使用好处:
注意:可选属性可以不实现,但是一旦实现就必须是声明时的类型
- interface dog{
- age: number;
- name: string;
- color?:string //可选实现 但是实现就必须是string类型的
- }
- let d1:dog
- d1={
- age:1,
- name:"小黑",
- color:"black" , //可写可不写,写了就必须是string类型 否则编译报错
- }
一些对象属性只能在对象刚创建的时候修改其值。 可以在属性名前用 readonly来指定只读属性。
readonly vs const:做为变量使用的话用 const,若做为属性则使用readonly。
注:TypeScript具有
ReadonlyArray类型,它与Array相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改。
- 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" ,因为它是只读属性
接口可以描述函数类型;为了使用接口表示函数类型,我们需要给接口定义一个调用签名。它就像是一个只有参数列表和返回值类型的函数定义。参数列表里面的每个参数都需要名称和类型。
声明式:作用域中直接声明一个函数
- function fn(n1: number, n2: any[], n3: Array
): 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]
}
传递给一个函数的参数个数必须与函数期望的参数个数一致。
- 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
{ - return [n1*2,n2,100] //严格模式下不能将undefined赋值给其他类型,非严格模式可以
- }
- fun(100) //n2是可选参数,可以传参,也可以不传参,不会报错
- fun(100,"haha")
还可以给参数设置默认值,在所有必选参数后面带默认值的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。
- function fun1(n2?:string,n1:number=100){
- //n1就是可选默认 虽然没有写? 但是只有可选参数才有默认值
- }
- fun1() //n1,n2都是可选参数,所以此处不传参
注:带默认值的参数不需要放在必选参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入
undefined值从而来获得默认值。
在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
]{ - return [[10,20,true],[10,20]]
- }
- fg(100,"haha",10,"xixi")
声明函数类型时用" => "," => "后必须写函数返回值类型 无返回值为空时也必须写void
变量的类型可以声明为函数类型:
- let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; };
- //这里的 => 不是箭头函数,而是表示在声明函数的类型
函数类型属于自定义类型,包含两部分:参数类型和返回值类型:
- //声明一个变量并指定类型为自定义的函数类型
- 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;
- }
只要参数类型是匹配的,那么就认为它是有效的函数类型,并不要求参数名一样,很多时候参数名是为了增加可读性
- let myAdd: (baseValue: number, increment: number) => number =
- function(x: number, y: number): number { return x + y; };
在函数和返回值类型之前使用( =>)符号,返回值类型是函数类型的必要部分,如果函数没有返回任何值,你也必须指定返回值类型为 void而不能留空。
自定函数类型代码往往很长,可以使用接口来封装该类型,之后使用接口来代表该类型
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}