当定义需要 import 语句时,如何扩展现有接口?

2024-03-21

我创建了一个自定义 Knockout 扩展器,但在扩展 Knockout 定义文件提供的现有接口时遇到了问题。

扩展器/Numeric.ts

import * as ko from "knockout";

function Extender(target: KnockoutObservable<number>, options: IOptions = {}): KnockoutObservable<number> {
    // ...
};

interface IOptions {
    // ...
}

export {Extender as NumericExtender, IOptions as INumericExtenderOptions}

Boot.ts

import * as ko from "knockout";
import {NumericExtender} from "./Extenders/Numeric";

class Boot {    
    public constructor() {
        ko.extenders.numeric = NumericExtender;
    }
}

让编译器了解ko.extenders.numeric,我需要扩展现有的接口:

interface KnockoutExtenders {
    numeric(target: KnockoutObservable<number>, options?: INumericExtenderOptions): KnockoutObservable<number>;
}

现在我在这里遇到了麻烦。为了访问INumericExtenderOptions,我需要一个import陈述:

import {INumericExtenderOptions} from "./Extenders/Numeric";

但是当添加了 import 语句后,该文件就被认为是一个模块,这使得无法扩展现有接口 https://stackoverflow.com/a/32959534/247702.

有没有办法做到这一点,或者我需要搬家IOptions到定义文件以避免import?


看来您正在使用全局版本的淘汰声明文件。我认为不可能从模块声明文件中扩展在全局范围内定义的接口。有几种解决方案:

  • 我认为最简单的解决方案是将您的接口放入全局命名空间中以及。对于 IOptions,这变为:

    // index.d.ts
    interface IOptions {
      // ¯\_(ツ)_/¯
    }
    
    interface KnockoutExtenders {
      numeric(target: KnockoutObservable<number>, options?: IOptions): KnockoutObservable<number>;
    }
    

    现在,您可以在任何地方使用数字函数访问 IOptions 和 KnockoutExtenders,因为声明文件仍然是全局的。

  • 另一种解决方案是拉入模块版本(我认为这是我的首选解决方案,只是因为您不会用所有淘汰类型污染全局名称空间)。在淘汰赛的情况下:typings install --save knockout。然后,您必须在需要时专门导入所需的类型。例如。你的 numeric.ts 变成

    // src/numeric.ts
    import { Observable } from "knockout"
    
    export function Extender(target: Observable<number>, options: IOptions = {}): Observable<number> {
      // ¯\_(ツ)_/¯
    };
    
    export interface IOptions {
      // ¯\_(ツ)_/¯
    }
    

    然后您可以在另一个声明文件中扩充敲除模块。例如:

    // index.d.ts
    import { Observable } from "knockout"
    import { IOptions } from './src/numeric'
    
    declare module "knockout" {
      interface Extenders {
        numeric(target: Observable<number>, options?: IOptions): Observable<number>
      }
    }
    

    然后您应该能够在应用程序中的任何位置使用增强的扩展器接口:

    // src/boot.js
    import { extenders } from "knockout"
    import { Extender } from "./numeric"
    
    class Boot {
      public constructor() {
        extenders.numeric = Extender
      }
    }
    
  • 最终的解决方案(可能最好地解决您的问题)是使用模块化声明文件,但要增强全局模块。您的 numeric.ts 保持不变,并且您的声明文件变为:

    import { IOptions } from './src/numeric'
    
    declare global {
      interface KnockoutExtenders {
        numeric(target: KnockoutObservable<number>, options?: IOptions): KnockoutObservable<number>
      }
    }
    

欲了解更多信息,请查看打字稿手册中有关声明合并的页面。 https://www.typescriptlang.org/docs/handbook/declaration-merging.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当定义需要 import 语句时,如何扩展现有接口? 的相关文章

随机推荐

  • npm、pip、pipenv 和 Poetry 包管理器之间的功能比较 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 主要特点是怎样的npm与之比较pip pipenv and Poetry https python poetry org 包管理器 我
  • 记录 ServiceStack Web 服务 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 用于记录基于 ServiceStack 的 Web 服务的选项有哪些 我不是在谈论单行字符串 我希望能够详细记录 可能很长 返回类型
  • 定义 CreateProjection 和 CreateMap

    在我的项目中 我使用实体框架进行 ORM 使用 Dto 类进行 api 响应 我使用 Automapper 在两者之间进行映射 当我需要直接从 EF 可查询中获取 Dtos 时 我会执行最后的操作ProjectTo lt gt 根据我的查询
  • 将 ggplot 标题放置在绘图的右上角

    我正在使用优秀的theme minimal 在 ggplot0 9 3 中找到 它具有白色背景 我想将绘图的标题放置在绘图右上角的自定义位置 在下面的例子中我知道x and y值 但我想知道是否有办法通过xmax and ymax值以确保文
  • 迭代Go地图获取索引

    为了使用revel s even https revel github io manual templates html even模板中的关键字我想在迭代时获取地图条目的索引range 有什么办法可以做到吗 我的地图具有以下结构 map s
  • dequeueReusableCellWithReuseIdentifier: 和 cellForItemAtIndexPath: 之间的区别

    我一直想知道为什么我的代码可以很好地工作cellForItemAtIndexPath 不与dequeueReusableCellWithReuseIdentifier 在获取集合视图单元格时 这是我的代码 这个效果很好 NSInteger
  • 为连续序列和分割向量创建分组变量

    我有一个向量 例如c 1 3 4 5 9 10 17 29 30 我想将形成规则 连续序列的 相邻 元素分组在一起 即在参差不齐的向量中增加 1 结果是 L1 1L2 3 4 5L3 9 10 L4 17L5 29 30 天真的代码 前 C
  • 如何确定 Qt 5 中的 QtWebEngine 在运行时使用的是哪个 chromium 版本?

    我在 Qt 5 中找不到任何函数来确定使用哪个 chromium 版本QtWebEngine 我不想在代码中硬编码 chromium 版本 因为我经常更新我的应用程序 并且每个版本中的 chromium 版本通常都会更改 而且 Qt 是向后
  • 目录相对 ZwCreateFile

    我必须为我的大学项目实施交叉视图文件完整性检查器 为此 我如何在内核模式下列出目录的文件 你的起点是ZwCreateFile http msdn microsoft com en us library windows hardware ff
  • 如何使用 ComPtr 中包装的 Direct3D 11 指针来获取 11.1 接口?

    我正在遵循教程 并将通常的初始化转换为使用 ComPtrs 直到这一行 ID3D11Device g pd3dDevice nullptr ID3D11Device1 g pd3dDevice1 nullptr Obtain the Dir
  • TriangleMesh JavaFX 中 getNormals() 方法的用途是什么

    我目前正在开发 JavaFX 3D 应用程序 并在 TriangleMesh 类中遇到 getNormals 方法 正如 Triangle Mesh 类用于创建用户定义的 Java FX 3D 对象一样 其中getPoints 用于添加Po
  • Python:subprocess.Popen() 的第一个实例非常慢

    我确信我错过了一些简单的东西 但是当使用子进程模块时 启动第一个子进程需要等待一段非常长的时间 gt 10 秒 第二个在第一个之后不久开始 有没有什么办法解决这一问题 代码如下 编辑 要添加 HWAccess 在 proc py 中 链接一
  • 如何将音频文件录制为 .m4a 格式?

    如何将音频文件录制为 m4a 格式 我正在使用下面的代码 public void startRecording throws IOException recorder new MediaRecorder path sdcard pithys
  • PyCharm:Scapy 未解决的参考

    我正在开发一个使用 scapy 用 python 编写的网络工具 我使用 Pycharm 作为 IDE 我的代码有效 因此 如果我运行它 一切都会按预期进行 我的问题是 PyCharm 给了我一些错误 它标志着每次使用IP TCP Ethe
  • 将 scanf 与 x86-64 GAS 组件结合使用

    我在尝试调用系统函数 scanf 以在我的 x86 汇编程序中工作时遇到了很多问题 目前我已经让它从标准中读取 但是它只会读取没有段错误的字符 我不知道为什么 指定字符串是 d 我在网上看到的 x86 中的 scanf 示例使用 quark
  • Git 忽略文件,而不删除它

    我有一个使用 GIT 进行版本控制的网站 我设置了一个系统 基本上可以自动部署我的更改master分支到我的生产服务器 也就是说 我的存储库中有一个 Web 挂钩 它会触发一个 PHP 脚本 该脚本本质上会启动一个git pull在服务器上
  • WatiN 搜索 google 后找不到文字

    我正在尝试运行一个简单的等待示例 搜索谷歌然后验证搜索结果 在 IE9 上 var browser new IE http www google com ncr browser TextField Find ByName q TypeTex
  • 从用于计算三角形和外接圆的 Swingworker 中重新绘制小程序

    我正在尝试复制找到的小程序here http www diku dk hjemmesider studerende duff Fortune 作为练习的一部分 该小程序使用 财富 的算法来生成两者 Voronoi 图和 Delaunay 三
  • 大背景图像和屏幕尺寸

    我正在创建一个网站 该网站将使用无法平铺的图像 我需要这张图像覆盖整个背景屏幕 但是 我希望它能够在大型显示器和小型显示器上运行 我应该制作一张大背景图像并使用它缩小它吗background size或者我应该创建不同尺寸的同一图像的多个版
  • 当定义需要 import 语句时,如何扩展现有接口?

    我创建了一个自定义 Knockout 扩展器 但在扩展 Knockout 定义文件提供的现有接口时遇到了问题 扩展器 Numeric ts import as ko from knockout function Extender targe