【问题标题】:Generated definition file (.d.ts) by typescript not working with package.json typings打字稿生成的定义文件(.d.ts)不适用于 package.json 类型
【发布时间】:2016-09-02 15:29:05
【问题描述】:

我使用 tsc 编译器的 --declaration 参数从我的 typescript 项目创建了一个定义文件 (d.ts)。

但是当我尝试在 npm package.json 上发布具有属性 typings 的包时,这个生成的定义文件显然不起作用。我创建了另一个项目来测试它。

它报错:“Exported external package file typings file '...d.ts' 不是模块。请联系包作者更新包定义”。 p>

这是我的源文件:

MyInterface.ts

export interface MyInterface
{
    MyProperty: string;
}

MyClass.ts

import {MyInterface} from './MyInterface';

export class MyClass implements MyInterface
{
    get MyProperty(): string
    {
        return "MyString";
    }
}

MyInheritedClass.ts

import {MyClass} from './MyClass';

export class MyInheritedClass extends MyClass
{
    public MyMethod(): number
    {
        return 1;
    }
}

tsc 命令是这样的:

tsc MyClass.ts MyInterface.ts MyInheritedClass.ts --declaration -t es5 -outFile "mydefinition.js" --module "system"

这是生成的定义:

mydefinition.d.ts

declare module "MyInterface" {
    export interface MyInterface {
        MyProperty: string;
    }
}
declare module "MyClass" {
    import { MyInterface } from "MyInterface";
    export class MyClass implements MyInterface {
        MyProperty: string;
    }
}
declare module "MyInheritedClass" {
    import { MyClass } from "MyClass";
    export class MyInheritedClass extends MyClass {
        MyMethod(): number;
    }
}

我还有其他事情要做吗,或者生成的定义在 package.json 类型中不起作用??

更新详情:

场景是我有 2 个项目:

  • 第一个项目是我生成库的地方,我将在其中发布到 npm,而 package.json 是我将类型属性链接到由 tsc -d 命令生成的 mydefinition.d.ts 文件的地方.

  • 我创建的第二个项目通过添加生成的包(带有类型)来测试第一个项目。

两个项目的链接和场景的另一个链接:

https://github.com/jvitor83/typings-packagejson

我认为问题在于第一个链接中的“您的定义文件应作为外部模块编写”。 但我想知道是否有办法让生成的这些定义放在 package.json 的 typings 属性中。

重现问题:

【问题讨论】:

  • 您是否尝试过使用typings.json
  • 我的打字经验是使用 Angular2,在 package.jsonscripts 部分中,您声明了一个用于打字的脚本,之后您可以使用它来安装您想要的类型定义,如下所示: npm run typings -- install jasmine --ambient --save
  • 我没有使用 angular2。我从一个纯打字稿项目制作了一个 npm 包。将定义放在typings中,json没有区别。它已经发现了“d.ts”文件,但问题是已经通知了错误。 “导出的外部包文件类型文件'...d.ts'不是模块。请联系包作者更新包定义”
  • 将模块选项从 system 更改为 CommonJS

标签: node.js typescript


【解决方案1】:

解决方案是:

1 - 添加单个文件“index.ts”,用于导出所有其他文件。

export * from "./MyInterface"
export * from "./MyClass"
export * from "./MyInheritedClass"

2 - 在构建过程中添加两个文件的编译/转译(一个用于声明,另一个用于单个 js 文件 [在 tsc 编译器中没有属性])

let tsConfigDeclaration = gulp_typescript({module: 'system', target: 'es5', declaration: true, removeComments: true });
let tsConfigOneFile = gulp_typescript({module: 'system', target: 'es5', declaration: true, removeComments: true, out: 'typings-packagejson.js'});

构建过程中的更多信息:https://github.com/jvitor83/typings-packagejson/blob/master/gulpfile.js

和索引文件:https://github.com/jvitor83/typings-packagejson/blob/master/app/src/typings-packagejson.ts

【讨论】:

  • 请更新您的问题,使其包含您更新后的需求。
【解决方案2】:

你什么时候收到这个错误?

我在另一个项目中使用了生成的 d.ts 文件,并且工作正常。

   /// <reference path="mydefinition.d.ts" />

  import { MyInterface } from "MyInterface";
  import { MyClass } from "MyClass";
  import { MyInheritedClass } from "MyInheritedClass";

  let x: MyInterface = { MyProperty: "hello!!" };
  let y: MyClass = new MyClass();
  let z: MyInheritedClass = new MyInheritedClass();

并且在编译时会生成 JS 文件,

 /// <reference path="mydefinition.d.ts" />
 "use strict";
 var MyClass_1 = require("MyClass");
 var MyInheritedClass_1 = require("MyInheritedClass");
 var x = { MyProperty: "hello!!" };
 var y = new MyClass_1.MyClass();
 var z = new MyInheritedClass_1.MyInheritedClass();

在某些 HTML 文件中使用它时是否遇到此错误?您是否在 HTML 中包含了 mydefinition.js 文件?

更新

根据您的更多详细信息,这是我可能提出的解决方案, 添加另一个名为 index.ts 的文件并从那里导出所有模块,

index.ts

    export * from "./MyInterface"
    export * from "./MyClass"
    export * from "./MyInheritedClass"

添加一个 tsconfig.json 文件以便于构建,

tsconfig.json

    {
     "version": "1.0.0",
     "compilerOptions": {
        "target": "ES5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": false,
        "declaration": true,
        "outDir": "lib/"
    }       
   }

注意我已经把它变成了一个 commonjs 模块(不确定它是否适合你的需要),使用 tsc 命令生成构建。它将生成如下所示的文件,它为所有 ts 文件添加了 js 文件,d.ts 也适用于所有模块,但是由于我们已经从单个文件中导出了所有模块,因此在 package.json 文件中为 npm 模块使用会更容易.

然后在你想要发布的 npm 模块中添加 package.json,如下所示,让我们考虑模块名称是 foo

package.json

    {
     "name": "foo",
     "author": "author name",
     "version": "1.0.0",
     "main": "lib/index.js",
     "typings": "lib/index.d.ts"
    }

现在在 node_module 中添加 foo 文件夹,第二个项目的最终结构如下所示,

最后在你的test.ts文件中导入并使用,

test.ts

    import { MyInterface, MyClass, MyInheritedClass } from "foo";

    let x: MyInterface = { MyProperty: "hello!!" };
    let y: MyClass = new MyClass();
    let z: MyInheritedClass = new MyInheritedClass();

【讨论】:

  • 我在 VSCode 中收到的消息。我在问题上添加了更多细节。
  • @jvitor83:根据您的新详细信息更新答案。
  • 我看到了您的解决方案,并且我知道编译为单个输出文件时生成的声明文件与 package.json 中的类型不兼容。我的替代方法是在构建时,对声明进行一次编译,然后将另一个编译为 .js 单个文件,该文件像您所说的那样导出所有其他文件。 @madhu-ranjan 这样我就可以满足“您的定义文件应该写为外部模块”。 github.com/jvitor83/typings-packagejson/commits/master 我最近的 2 次提交表明了这一点。我将进行更多测试,看看是否可以在不需要该文件的情况下进行此操作
  • 您能用我提出的解决方案解决问题吗?
  • 部分...我使用了一个文件导出所有其他文件的想法(从“文件”导出*)。但是在构建过程中,我做了两个步骤,一个用于声明,另一个用于单个 js。因为单个文件生成的声明在 package.json 中不是有效的类型。 let tsConfigDeclaration = gulp_typescript({module: 'system', target: 'es5', declaration: true, removeComments: true }); let tsConfigOneFile = gulp_typescript({module: 'system', target: 'es5', declaration: true, removeComments: true, out: 'typings-packagejson.js'});
猜你喜欢
  • 2018-03-04
  • 2020-09-08
  • 2020-10-14
  • 2018-09-13
  • 2019-01-02
  • 2018-05-14
  • 2023-03-23
  • 2018-08-30
  • 2019-05-30
相关资源
最近更新 更多