扩展typescript的YetTyped定义文件

时间:2017-11-21 20:57:37

标签: javascript node.js typescript definitelytyped

我收到以下错误:

  

src / models / priceAdjustment.ts(55,2):错误TS2345:类型'{as:string; foreignKey:string; gql:any; }'不能赋值给'AssociationOptionsHasMany'类型的参数。     Object literal只能指定已知属性,'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

1 个答案:

答案 0 :(得分:2)

您可以通过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的好处是严格(呃)打字。