TypeScript4-接口

这篇具有很好参考价值的文章主要介绍了TypeScript4-接口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

接口(Interfaces)是 TypeScript 中的一个重要特性。接口是一个强大的方式来定义和保证代码符合某种特定结构。接口可以用来描述对象的结构,作为类的公共接口,或定义为函数或构造函数的类型。

一、对象类型接口

1. 对象类型接口的基本语法

下面是一个模拟处理后端返回的数据的场景案例。

// 对象类型接口
interface Some {
    id: number;
    name: string;
}

interface Res {
    data: Some[]
}

function render(target: Res) {
    target.data.forEach((value) => {
        console.log(value.id + ' ' + value.name);
    });
}

var information = {
    data: [
        { id: 1001, name: 'zhangsan' },
        { id: 1002, name: 'lisi'}
    ]
}

render(information);
// "1001 zhangsan"
// "1002 lisi"

在这个案例中,我们定义了一个对象接口 Some,类型为这个接口的对象需要有 id 和 name 两个属性。又定义了一个接口 Res,表示后端返回的数据,类型为这个接口的对象需要有一个 data 属性,类型为数组,数组的元素的类型为 Some,即一个对象数组。我们还定义了一个 render 函数,用来处理后端返回的数据,参数是一个类型为 Res 的对象。

接下来我们定义了一个对象 information,遵循 Res 接口定义的规范。调用 render 函数处理这个对象,得到了我们预期的输出。

2. 对象类型接口检查机制

很多时候后端返回的数据并不是完全符合我们定义的接口规范,data 中的元素经常会有一些其他属性。修改 information 对象:

var information = {
    data: [
        { id: 1001, name: 'zhangsan', message: 'hello interface' },
        { id: 1002, name: 'lisi'}
    ]
}

运行后我们发现仍然可以编译通过,这是 TS 接口的一个特性。

如果我们使用对象类型注解,如:

let obj: { x: number, y: number } = {x: 1, y: 2, z: 3};

就会报错:Type '{ x: number; y: number; z: number; }' is not assignable to type '{ x: number; y: number; }'. Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: number; }'.,表示类型不匹配,多出了一个属性 z,对象的结构必须和对象类型注解一致。

但使用对象类型接口时,只要这个对象符合接口定义的规范,即有接口中定义的所有属性,且类型正确,即使有额外的属性,也可以通过类型检查。这种情况被称作 “鸭式辨型法” 或 “结构性子类型化”。

3. 对象字面量场景

上述案例中,如果我们传给 render 函数的参数不是一个对象,而是一个对象字面量,如:

render({
    data: [
        { id: 1001, name: 'zhangsan', message: 'hello interface' },
        { id: 1002, name: 'lisi'}
    ]
});

会出现报错:Type '{ id: number; name: string; message: string; }' is not assignable to type 'Some'. Object literal may only specify known properties, and 'message' does not exist in type 'Some'.,表示对象字面量可以指定已知的属性,并且 message 属性在 Some 接口中不存在。

使用变量传值和使用字面量传值这两种写法的效果是一模一样的,为什么会出现报错呢?原因在于 TS 对对象字面量会进行一些额外的属性检查。

绕开这种检查有3种方式:

(1) 使用变量存储对象字面量,也就是上面的案例,这是最简单的方法。

(2) 使用类型断言

render({
    data: [
        { id: 1001, name: 'zhangsan', message: 'hello interface' },
        { id: 1002, name: 'lisi'}
    ]
} as Res);

在对象字面量后加上类型断言 as Res,表示告诉编译器这是一个对象字面量,但我已经知道它会遵循 Res 接口定义的规范。

还有一种类型断言方式,使用尖括号来指定类型。如:

render(<Res>{
    data: [
        { id: 1001, name: 'zhangsan', message: 'hello interface' },
        { id: 1002, name: 'lisi' }
    ]
});

这种方式并不推荐使用,因为某些情况下编辑器可能认为尖括号(<>)是一个标签,会出现其他问题(如在 TS 演练场就会报错)。

(3) 使用字符串的索引

告诉编辑器,我当前的 Some 接口中,除了 id 和 name 外,很可能还会有一些多余的字段存在,你要放过它们。具体方法如下:

interface Some {
    id: number;
    name: string;
    [propName: string]: any; // 字符串索引,表示索引的类型为 string,值的类型为 any
}

render({
    data: [
        { id: 1001, name: 'zhangsan', message: 'hello interface' },
        { id: 1002, name: 'lisi' }
    ]
});

这个时候我们也能绕开类型检查。

这里还有另一种方法,上面这个案例我并不知道多余字段的名称,也不知道多余字段有多少个,因此就使用了字符串索引。但假设我已经知道多余字段的名称,就可以按下面这样做:

interface Some {
    id: number;
    name: string;
    message?: string;
}

render({
    data: [
        { id: 1001, name: 'zhangsan', message: 'hello interface' },
        { id: 1002, name: 'lisi' }
    ]
});

message 属性后面的问号代表 message 这个属性可以有也可以没有,即可选属性。这样做也可以通过类型检查。

TS 还可以声明只读属性,只需要在属性名前面加上 readonly 即可。如:

interface Some {
    readonly id: number;
    name: string;
    message?: string;
}

function render(target: Res) {
    target.data.forEach((value) => {
        console.log(value.id + ' ' + value.name);
        value.id++;
    });
}

在这个案例中,我们将 id 属性声明成只读属性,又在 forEach 中对 id 的值进行自增。会出现报错:Cannot assign to 'id' because it is a read-only property.,表示不能给 id 赋值,因为它是一个只读属性。

二、函数类型接口

首先先来复习一下,在变量上定义函数的类型的方法:

let fun: (x: number, y:number) => number;
fun = (x, y) => x + y;

1. 类型别名

type fun = (x: number, y:number) => number;
let fun: fun = (x, y) => x + y;

 我们定义了一个类型别名 fun,表示一个函数类型。又定义了一个函数 fun,类型为 fun。这种写法和在变量上定义函数的类型的写法类似,但本质是不同的,前者可以一对多,后者只能一对一。

类型别名也适用于其他类型,如:

type num = number;
let fun: num = 1;

2. 函数类型接口的基本语法

使用函数类型接口,我们不需要去定义函数的名称,直接定义函数的参数和返回值的类型就可以了。

// 函数类型接口
interface Func {
    (x: number, y: number): number;
}

实现方式如下: 

let fn: Func = (x, y) => x + y;

使用这个函数时需要遵循 Func 接口定义的的参数和返回值类型。

3. 混合类型接口

混合类型接口可以有不同类型的成员。

// 混合类型接口
interface Func {
    (): void; // 1
    version: string, // 2
    isObject(x: object): boolean // 3
}

接下来我们来实现这个接口:

// 混合类型接口
let fn: Func = () => {};
fn.version = '1.0.0';
fn.isObject = (x) => {
    return typeof x === 'object';
};

这里我们定义了一个变量 fn,它的类型是 Func,它的值为一个没有参数没有返回值的函数,符合条件1;又给它定义一个属性 version 为一个字符串,符合条件2;再定义它的 isObject 属性为一个函数,有一个参数 x,返回类型为布尔值。

到这一步运行后仍然会出现报错:Type '() => void' is missing the following properties from type 'Func': version, isObject,表示还不符合 Func 的第2和第3个条件。

这里我们需要通过类型断言,来告诉编辑器 fn 变量满足 Func 定义的类型规范。如下所示:

let fn: Func = (() => {}) as;
fn.version = '1.0.0';
fn.isObject = (x) => {
    return typeof x === 'object';
};

这里我们才算完成对 Func 接口的实现。文章来源地址https://www.toymoban.com/news/detail-452402.html

到了这里,关于TypeScript4-接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】

    相关文章: Django实现接口自动化平台(十二)自定义函数模块DebugTalks 序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测

    2024年02月17日
    浏览(41)
  • TypeScript中的泛型(泛型函数、接口、类、泛型约束)

    一、泛型函数 TypeScript 泛型是一种可以使代码具有更高的可重用性和泛化能力的特性 。通过泛型,我们可以定义一种通用的类型或函数,使其能够应对多种类型的输入。泛型在类、函数、接口等多种场景下都可以使用。 具体来说,在定义泛型函数时,我们可以使用来表示一

    2024年02月11日
    浏览(44)
  • 面试题-TS(三):TypeScript 中的接口是什么?它们有什么作用?

    面试题-TS(3):TypeScript 中的接口是什么?它们有什么作用? 在TypeScript中,接口是一种用于定义对象属性和行为的工具。它们充当了代码之间的契约,描述了对象应该具有的属性和方法。通过使用接口,我们可以提供更好的类型检查、模块化和代码复用。 一、接口的定义和使

    2024年02月15日
    浏览(44)
  • TypeScript深度剖析:TypeScript 中接口的应用场景?

    接口 是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的 类 去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法 简单来讲,一个接口所描述的是一个对象相关的属性和方法,但并不提供具体创建此对象实例

    2024年02月07日
    浏览(35)
  • typeScript(接口篇)

    TypeScript的核心原则之一是对值所具有的 结构 进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。 下面通过一个简单示例来观察接口是如何工作的: 类型检查器会查看

    2024年02月10日
    浏览(30)
  • Typescript 之接口 interface(详解)

    TS新增了一个重要概念:接口, 分为对象类型接口和函数类型接口 接口可以约束对象,函数,类的结构和类型,是一种代码协作必须遵守的契约 Interface 是一种描述对象或函数的东西。你可以把它理解为形状,一个对象需要有什么样的属性,函数需要什么参数或返回什么样的值,数

    2024年02月10日
    浏览(43)
  • TypeScript--接口interface的定义,实现,继承

    可浏览博客主页的 TypeScript 专栏,会陆续添加相关文章,有问题或者可以优化的地方也希望大大门告知 共同进步 :) ts版本 Version 4.8.4 TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作

    2023年04月12日
    浏览(38)
  • 【TypeScript】TS接口interface类型(三)

    一、前言 TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。这些方法都应该是抽象的,需要由具体的类去实现,然后第三方

    2024年02月14日
    浏览(43)
  • 【TypeScript】TypeScript中的泛型

    定义一个函数或类时,有些情况下无法确定其中要使用的具体类型(返回值、参数、属性的类型不能确定),此时泛型便能够发挥作用。 举个例子: 上例中,test函数有一个参数类型不确定,但是能确定的时其返回值的类型和参数的类型是相同的,由于类型不确定所以参数和

    2024年02月09日
    浏览(45)
  • TypeScript 学习笔记(二):接口与类型别名、字面量类型

    在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些

    2024年02月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包