ts的接口


TypeScript中的接口可以用来描述对象外形,可以用来描述函数类型,也可以像java接口那样用来抽象方法。接下来会一一介绍。

描述对象外形

必需属性
interface Animal{
    food:string;
    size:string;
}
function printInfo(a:Animal){
    console.log(a.food,a.size);
}

接口中,属性名右侧的:表示是必需属性
food:stringfood是必需属性,且是字符串类型;size:stringsize是必需属性,且是字符串类型。
因此,传入printInfo的参数对象必须包含foodsize这两个字符串属性,不能多,也不能少,必须刚刚好。否则,编译不过。
在这里插入图片描述

如果想多传属性呢?

有以下三种方法。

方法1 传参时不要使用对象字面量,使用一个变量
const animal = {
    food:"meat",
    size:"medium",
    location:"south"
}
printInfo(animal);
方法2 使用字符串索引签名
interface Animal{
    food:string;
    size:string;
    [propName:string]:any
}
printInfo({
    food:"meat",
    size:"medium",
    location:"south"
});

[propName:string]:any中的propName是随便取的,[a:string]:any[b:string]:any等等都行,只要你乐意。

字符串索引签名

const obj:MyObj = { a:"hello", b:"world" }obj["a"]的值"hello"obj["b"]的值是"world"
"a""b"就是字符串索引

interface MyObj{
    [propName:string]:string
}
const obj:MyObj = {
    a:"hello",
    b:"world"
}

在这里插入图片描述
使用字符串索引签名,变量obj中可以包含任意多的属性,只要属性名是string类型,属性值是string类型。
TypeScript支持两种索引签名数字索引签名字符串索引签名
顺便了解下数字索引签名

数字索引签名

const arr=["hello","world"];arr[0]的值是"hello"arr[1]的值是"world"
01就是数字索引
接口可以用来描述对象的外形,数组也是对象啊。看看接口会怎样描述数组。

interface StringArray{
    [index:number]:string
}
const arr:StringArray = ["hello","world"];
/*
const arr:StringArray = {
    0:"hell0",
    1:"world"
}
*/

[index:number]:string就是数字索引签名index也是随意取的。
变量arr, 索引可以是任意数值,只要该索引对应的值是string类型。
const obj:MyObj = { 1:true, 2:"world" }就不行,因为索引1对应的值是boolean类型。
虽然数字索引签名可以用来描述数组,但并不常用。
要定义数组,下面两种方式更常见:

  1. 元素类型[],如let arr:number[] = [1,2,3]
  2. 数组泛型,Array<元素类型>,如let arr:Array<number> = [1,2,3]
方法3 使用类型断言

类型断言的关键字是as
类型断言其实是三十六计的“明修栈道,暗度陈仓”,欺骗编译器说,“看到没,看到没,传入的是Animal类型哈”,然而并不是,还偷偷地塞了个location

interface Animal{
    food:string;
    size:string;
}
function printInfo(a:Animal){
    console.log(a.food,a.size);
}
printInfo({
    food:"meat",
    size:"medium",
    location:"south"
} as Animal);
如果想少传属性呢?
方法1 类型断言
interface Animal{
    food:string;
    size:string;
}
function printInfo(obj:Animal){
    console.log(obj.food,obj.size);
}
printInfo({
    food:"meat"
} as Animal);

当然,依然可以借"类型断言"来"暗度陈仓"。但这样,缺点很明显:编译倒是过了,但真正运行的时候却出错了。因为最需要的东西,你恰巧没带。
所以 下面这种方法可能更好些。

方法2 可选属性
interface Animal{
    food:string;
    size?:string;
}
function printInfo(a:Animal){
    console.log(a.food,a.size);
}
printInfo({food:"meat"});
printInfo({
    food:"meat",
    size:"medium"
})

接口中,属性名右侧的?:表示是可选属性
size就是可选属性。调用printInfo时,传入的对象参数时,size可有可无。

除了必需属性、可选属性,还有只读属性。

只读属性
interface Animal{
    readonly food:string;
    size?:string;
}
var a:Animal = {
    food:"meat",
    size:"medium"
}
a.food = "grass"; //Cannot assign to 'food' because it is a read-only property

readonly属性值允许在刚刚创建的时候赋值,之后就不能改动了。
明明吃肉长大的,忽然要人家改吃草,敢问:谁受得了!!

readonly也可用于索引签名。

  • readonly应用于数字索引签名
//数字索引签名
interface StringArray{
    readonly [index:number]:string
}
let arr:StringArray = ["hello","world"];
arr[0] = "welcome";//Index signature in type 'StringArray' only permits reading

其实,如果想让数组只读,还有一种更简单的方式,使用ReadonlyArray<string>

let arr:ReadonlyArray<number> = [1,2,3];
arr[0] = 4;//Index signature in type 'readonly number[]' only permits reading.
  • readonly应用于字符串索引签名
//字符串索引签名
interface StringArray{
    readonly [propName:string]:string
}
let arr:StringArray = {
    a:"hello",
    b:"world"
}
arr["a"] = "world";//Index signature in type 'StringArray' only permits reading.

描述函数类型

interface SearchFunc{
    (source:string,subString:string):boolean;
}

const find:SearchFunc = function(source,subString){
    return source.search(subString) > -1;
}
const find2:SearchFunc = function(src,sub){
    return src.search(sub)>-1;
}

在这里插入图片描述
(source:string,subString:string):boolean的意思是,
a,函数接受两个参数,对参数名没有要求,可以叫"source",也可以叫"src",随便,都行;
b,第一个参数必须是|兼容string类型,第二个参数也必须是|兼容string类型;
c,函数必须有返回值,且返回值类型必须是boolean类型。

接口继承接口

前面我们讲了,接口可以用来描述对象外形,可以用来描述函数类型。也就是说,接口就是一种类型。因此,接口继承接口,就是扩充了类型。

//动物  
interface Animal{
    food:string;
    size:string;
}
//猫科动物
interface Feline{
    location:string;
    eat:()=>void;
}
//狮子
interface Lion extends Animal,Feline{
}

let lion:Lion =  {
    food:"meat",
    size:"medium",
    location:"Africa",
    eat:function(){
    }
} 

接口继承类

类就是类型,接口也是类型。
所以接口继承类和接口继承接口一样,都是扩充类型。

//动物 
class Animal{
    food:string;
    size:string;
}
//猫科动物
class Feline{
    location:string;
    eat:()=>void;;
}
//狮子
interface Lion extends Animal,Feline{
}

let lion:Lion =  {
    food:"meat",
    size:"medium",
    location:"Africa",
    eat:function(){
    }
} 

类似java接口,用来抽象方法

接口中的方法全部是抽象方法,只有方法签名,没有方法体。
实现接口的类必须实现接口中的全部方法。

interface Animal{
    eat();
}
class Lion implements Animal{
    constructor(food:string){
    }
    eat(){
        console.log("eating meat");
    }
}
const lion:Lion = new Lion("meat");
lion.eat();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值