我们如何在 TypeScript 中为非全局接口创建扩展方法?

Posted

技术标签:

【中文标题】我们如何在 TypeScript 中为非全局接口创建扩展方法?【英文标题】:How can we create extension methods for non-global interfaces in TypeScript? 【发布时间】:2019-04-11 07:42:27 【问题描述】:

我目前正在学习 TypeScript,但对如何为非全局接口实现扩展方法感到非常困惑。考虑以下示例:假设我有一个 interface 定义一个 Cart 像这样:

interface Cart 
    id(): string,
    name(): string,
    quantity(): number

    /* Other methods */

然后,我想添加一个类似下面的扩展方法:

Cart.prototype.isValid = function() 
    return this.quantity() > 0;

这显然不起作用,因为Cart 不是一个类型,但我很困惑,因为Promise 也被定义为interface,但我可以成功地向它添加扩展方法。例如:

declare global 
    interface Promise<T> 
        hello(): string
    


Promise.prototype.hello = function() 
    return "Hello!";


export ;

是否可以扩展像Cart 这样的非全局接口,如果可以,我该怎么做?

【问题讨论】:

不要认为它可能或有用。在运行时不应更改接口。否则编译过程中将无法进行类型检查。 你可以做的是创建另一种类型,它将是几个接口的组合:type Blah = Foo &amp; Bar 您正在寻找模块扩充和接口合并typescriptlang.org/docs/handbook/declaration-merging.html 【参考方案1】:

在您的情况下, Cart 只是一种类型。没有对象,您不能扩展类型/接口引用的原型。没有要扩展的原型,你可以用一些实现 Cart 的对象来做。

对于 Promise,它是一个浏览器 API,如果您在浏览器上进行控制台并键入 Promise,您将看到那里有一个对象。当您像您提供的示例一样扩展承诺原型时,您不是在扩展接口,而是在扩展此对象。

如果您想这样做,一种可能的解决方案是界面组合,例如:

interface CartSpecial extends Cart 
    ...

【讨论】:

所以Promise 绝对是一个对象,但问题是它的TypeScript 定义是interface。我的问题是,它是如何/为什么起作用的,但不是我的 Cart 示例?我需要做些什么来为Cart 实现与Promise 相同的行为? 你不能这样。 TypeScript 知道你的 Promise 是一些提供的 API。您没有扩展接口,您是在 promise.d.ts 文件上声明的全局变量(被浏览器 api 覆盖)。当您扩展 Promise 时,您正在扩展 declare var Promise: PromiseConstructor;,其中声明了原型:interface PromiseConstructor /** * A reference to the prototype. */ readonly prototype: Promise&lt;any&gt;;

以上是关于我们如何在 TypeScript 中为非全局接口创建扩展方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何添加自定义 TypeScript 全局接口

如何在导航栏中为非 rootviewcontroller 的 tableviewcontroller 添加编辑按钮

如何在python中为非数字变量制作直方图

如何在张量流中为非分类对象创建一个类?

如何在win API的creatnamedpipe方法中为非管理员权限帐户添加安全属性

如何在 TypeScript 中为类属性动态分配值