什么是接口?
可以使用接口来描述对象、命名和参数化对象的类型,以及将现有的命名对象类型组成新的对象类型。简单说就是 描述变量类型的。
示例:
// 定义接口
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 (类型别名) 有何不同?
-
语法上 type 后面有 =,interface 没有; -
type 可以描述任何类型组合,interface 只能描述对象结构; -
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 }
-
多次声明的同名 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;
}
声明和实例化接口规范
interface 关键字开头 接口名称不能是类型系统中预定义的类型名称之一 接口名称为 PascalCase 形式(帕斯卡命名法) 定义该接口的属性(或成员)及其类型。属性可以为必需、可选或只读属性
属性类型 | 说明 | 示例 |
---|---|---|
必须 | 除非另行指定,否则所有属性都是必需的。 | 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();
知识检查
-
接口的主要工作是什么?
-
描述对象的属性和返回类型。
2. 当省略接口中的属性时,如何防止类型系统引发错误?
-
将属性设置为可选属性。
3. 用另一个接口扩展一个接口会发生什么情况?
-
必须从所有接口实现所有必需的属性。
-
思考 为什么下面这句话不对?
-
如果属性具有完全相同的名称,则多个接口可以具有相同的属性。
// 继承时 属性名称相同 但是类型不同无法继承 但是可以收窄继承
interface A {
x:number;
}
interface B extends A{
x:string;
}
// 接口“B”错误扩展接口“A”。
// 属性“x”的类型不兼容。
// 不能将类型“string”分配给类型“number”。
原文始发于微信公众号(王大可996):TypeScript学习笔记(7)-接口
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/205225.html