TypeScript学习笔记(7)-接口

什么是接口?

可以使用接口来描述对象、命名和参数化对象的类型,以及将现有的命名对象类型组成新的对象类型。简单说就是 描述变量类型的。

示例:

// 定义接口
interface Person {
    firstName: string;
    lastName: string;
    fullName(): string;
}

//声明 Person类型的变量
let wdk: Person = {
    firstName: 'w',
    lastName: 'dk',
    fullName(): string {
        return this.firstName + ' ' + this.lastName
    }
}

console.log(wdk.fullName()) // 输出 "w dk"

wdk.firstName=100; //提示 不能将类型“number”分配给类型“string”。

接口在编译时可以验证参数,属性类型 以及返回类型确保可以编译成功,而不用等运行时发现错误。

 使用接口的原因:

类型检查,避免错误。

使开发保存一致性,因为实现接口的每个对象都在相同的类型定义下运行。

描述现有的 JavaScript API 并阐明函数参数和返回类型。可以清楚的知道Api传入和返回类型。

interface (接口)与 type (类型别名) 有何不同?

  1. 语法上 type 后面有 =,interface 没有;
  2. type 可以描述任何类型组合,interface 只能描述对象结构;
  3. interface 可以继承自(extends)interface 或对象结构的 type。type 也可以通过 & 做对象结构的继承;

     
    // interface 继承
    interface Shape {
        x: number;
        y: number;
      }
      
      // 继承扩展
      interface Square extends Shape {
        width: number;
        height: number;
      }
      
      const rect: Square= { x: 0, y: 0, width: 0, height: 0 };
    
    
    
    //type 继承
    type Shape = {
        x: number;
        y: number;
    }
    
    type Square = Shape & { r: number }
    
    const circle: Square = { x: 0, y: 0, r: 8 }
  4. 多次声明的同名 interface 会进行声明合并,type 则不允许多次声明;
    4.1 同名属性的不能进行类型覆盖修改,类型必须完全一致 x必须为number

//同名属性的不能进行类型覆盖修改,类型必须完全一致 x必须为number

// interface 支持声明合并,文件下多个同名的 interface,它们的属性会进行合并
interface Square {
    x: number;
}

interface Square {
    // 后续属性声明必须属于同一类型。属性“x”的类型必须为“number”,但此处却为类型“string | number”。ts(2717)
    x: string | number; 
    y: number;
}
const square: Square = { x: 10, y: 30 };

         4.2 extends 可以将属性的类型进行收窄,比如从 string | number 变成 string
       

// extends 可以将属性的类型进行收窄,比如从 string | number 变成 string
// 父级
interface Shape {
    x: string | number;
    y: number;

}

interface Square extends Shape {
    x: number;
    area(): number;
}

let squareArea: Square = {
    x: 10,
    y: 10,
    area(): number {
        return this.x * this.y;
    }
}

console.log(squareArea.area())

        4.3 type 则不允许多次声明。 

// type 不支持声明合并,一个作用域内不允许有多个同名 type。
// 报错:标识符“Square”重复。
type Square = {
    x: number;
}

// 报错:标识符“Square”重复。
type Square = {
    y: Square;
}


声明和实例化接口规范

1.  interface 关键字开头

2. 接口名称不能是类型系统中预定义的类型名称之一

3. 接口名称为 PascalCase 形式(帕斯卡命名法)

4. 定义该接口的属性(或成员)及其类型。 属性可以为必需、可选或只读属性

属性类型说明示例
必须除非另行指定,否则所有属性都是必需的。firstName: string;
可选在属性名称的末尾添加问号 (?)。 对于不是必需的属性,请使用此属性。 这可以防止类型系统在省略该属性时引发错误。firstName?: string;
只读在属性名称的前面添加 readonly 关键字。 对于只应在首次创建对象时修改的属性,请使用此属性。readonly firstName: string;

 实现 厨师在 做饭 烹饪 烤面包 一个接口:


// 王大可是大厨
interface Chef {
    name: string;
    fat?: boolean;
    prepareMeal(): void;
    bake(): void;
    cook(): void;
}

// 实现接口
const chef: Chef = {
    name: "王大可",
    prepareMeal: function () {
        console.log(this.name + " 正在准备菜肴...");
    },
    bake: function () {
        console.log(this.name + " 正在烤面包...");
    },
    cook: function () {
        console.log(this.name + " 正在烹饪菜肴...");
    }
};

chef.prepareMeal(); // 输出 "王大可 正在准备菜肴..."
chef.bake(); // 输出 "王大可 正在烤面包..."
chef.cook(); // 输出 "王大可 正在烹饪菜肴..."


//定义可选属性 是否肥胖
interface MichelinThree extends Chef {
    name: string;
    prepareMeal(): void;
    bake(): void;
    cook(): void;
}

const michelinThree: MichelinThree = {
    name: "米其林三星-张三",
    prepareMeal: function () {
        console.log(this.name + " 正在准备菜肴...");
    },
    bake: function () {
        console.log(this.name + " 正在烤面包...");
    },
    cook: function () {
        console.log(this.name + " 正在烹饪菜肴...");
    }
};

michelinThree.prepareMeal(); // 输出 "米其林三星 正在准备菜肴..."

 
创建可索引类型

interface MyInterface {
    [index: number]: string;
}
const myArray: MyInterface = ["a", "b", "c"];
console.log(myArray[0]); // 输出a


使用接口描述 JavaScript API

可以使用接口描述现有的 JavaScript API 并阐明函数参数和返回类型。 接口使你能够清楚地了解 API 的期望值和返回值。

const fetchURL = 'https://jsonplaceholder.typicode.com/posts'
interface Post {
    userId: number;
    id: number;
    title: string;
    body: string;
}

// 定义一个异步函数,用于获取指定URL的帖子
async function fetchPosts(url: string) {
    // 使用fetch函数获取指定URL的响应
    let response = await fetch(url);
    // 使用json函数将响应体转换为json格式
    let body = await response.json();
    // 返回转换后的json格式的帖子数组
    return body as Post[];
}

// 定义一个异步函数,用于显示帖子
async function showPost() {
    // 使用fetchPosts函数获取指定URL的帖子
    let posts = await fetchPosts(fetchURL);
    // 获取帖子数组中的第一个帖子
    let post = posts[0];
    // 打印帖子的id
    console.log('Post #' + post.id)
    // 打印帖子的作者,如果作者id为1,则打印管理员,否则打印作者id
    console.log('Author: ' + (post.userId === 1 ? "Administrator" : post.userId.toString()))
    // 打印帖子的标题
    console.log('Title: ' + post.title)
    // 打印帖子的内容
    console.log('Body: ' + post.body)
}
// 调用showPost函数
showPost();


知识检查 


1. 接口的主要工作是什么?
        描述对象的属性和返回类型。

2. 当省略接口中的属性时,如何防止类型系统引发错误?
        将属性设置为可选属性。

3. 用另一个接口扩展一个接口会发生什么情况?

        必须从所有接口实现所有必需的属性。


4. 思考 为什么下面这句话不对?
如果属性具有完全相同的名称,则多个接口可以具有相同的属性。

// 继承时 属性名称相同 但是类型不同无法继承 但是可以收窄继承
interface A {
    x:number;
}
interface B extends A{
    x:string;
}

// 接口“B”错误扩展接口“A”。
//   属性“x”的类型不兼容。
//     不能将类型“string”分配给类型“number”。

 

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值