【问题标题】:Extend typescript definitelyTyped definition file扩展 typescript 肯定类型的定义文件
【发布时间】:2017-11-22 21:43:31
【问题描述】:

我收到以下错误:

src/models/priceAdjustment.ts(55,2): error TS2345: Argument of type '{ as: string;外键:字符串; gql:任何; }' 不可分配给“AssociationOptionsHasMany”类型的参数。 对象字面量只能指定已知属性,而 'AssociationOptionsHasMany' 类型中不存在 'gql'。

错误很明显,我正在尝试分配一个不存在的“gql”键(我正在附加它,以便稍后在我的代码中的其他地方访问它)。

我想做的是扩展model.hasMany interface here,并添加我自己的密钥。这可能吗?如果是,我该怎么做?

我目前的解决方法是在传递对象之前将其转换为<any>,这感觉像是一种肮脏的解决方法。

我尝试了以下方法:

import Sequelize from 'sequelize';

export declare module Sequelize {
    export interface MyAssociationOptionsHasMany extends Sequelize.AssociationOptionsHasMany {
        gql?: any
    }
    export interface MyAssociations extends Sequelize.Associations {
        hasMany(target: Sequelize.Model<any, any>, options?: MyAssociationOptionsHasMany): void;
    }
}

现在我收到以下错误:

TypeError: Cannot read property '239' of undefined
    at getDeclarationSpaces (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:33121:54)
    at checkExportsOnMergedDeclarations (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:33067:41)
    at checkModuleDeclaration (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:35036:17)
    at checkSourceElement (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:35505:28)
    at Object.forEach (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:275:30)
    at checkSourceFileWorker (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:35566:20)
    at checkSourceFile (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:35551:13)
    at getDiagnosticsWorker (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:35604:17)
    at Object.getDiagnostics (C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:35593:24)
    at C:\Users\user\AppData\Roaming\npm\node_modules\typescript\lib\tsc.js:56188:85

【问题讨论】:

标签: javascript node.js typescript definitelytyped


【解决方案1】:

您可以通过Declaration Merging 执行此操作。我发现这个工作的最好方法是将库导入“扩展”文件并从那里扩展库。例如,

extensions/library-name.extension.ts:

import AssociationOptionsHasMany from '/path/to/definition';
import 'library-name';

declare module 'library-name' {
  interface InterfaceToExtend {
    hasMany(options: AssociationOptionsHasMany): ReturnType;
  }
}

在上面的例子中,我们想要扩展在library-name 模块中创建的接口。由于我们使用导入,TypeScript 会自动为该文件创建一个模块,因此我们必须告诉 TypeScript 我们要扩展 library-name 模块中的接口,而不是为该文件创建的模块。为此,我们只需 declare 使用与我们导入的库相同的名称的模块。

在告诉 TypeScript 应该在哪个模块中扩展接口之后,我们只需通过定义一个与应该扩展的接口同名的接口并添加我们需要的任何内容来使用声明合并。在这种情况下,这将是一个新方法,它将我们想要传递的特定类型作为参数。

我还必须更新tsconfig.json 文件,以便首先加载扩展。您可以通过在应用程序的其余部分之前包含 extensions 目录来做到这一点:

{
  /* Blah, settings, blah */
  includes: ['./app/extensions/*.ts', './app/**/*.ts'],
  /* Blah, settings, blah */
}

如果您使用的是 Sublime,它可能仍然会抱怨,但实际上编译代码或退出 Sublime 并重新打开它似乎工作正常。

警告。 声明合并功能强大,但可能导致意外行为。一般来说,尽量避免扩展您(或其他人)在别处定义的组件。如果可能表明您未正确使用这些组件或需要重构。请记住,TypeScript 的好处是严格(呃)类型。

【讨论】:

  • 我已经用我遇到的另一个问题更新了我的问题。
  • @FrankerZ 尝试使用export interface MyAssociationOptionsHasMany { /*...*/ 而不是export interface MyAssociationOptionsHasMany extends Sequelize.MyAssociationOptionsHasMany { /* ... */ } 和类似的MyAssociations。我对 Sequelize 不太熟悉,所以我不能提供太多关于 Sequelize 的细节。
  • @FrankerZ 请考虑接受这个答案。它回答了你的问题:)
猜你喜欢
  • 2019-02-12
  • 2014-06-06
  • 2022-11-11
  • 2019-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
相关资源
最近更新 更多