网站搜索

node.js - TypeScript 生成的定义文件 (.d.ts) 与 package.json 中的 typings 不兼容


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

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

它报错信息为:"导出的外部包文件 typings 文件 '...d.ts' 不是模块。请联系包作者更新包定义"。

这是我的源文件:

MyInterface.ts

export interface MyInterface
{
    MyProperty: string;
}

MyClass.ts

import {MyInterface} from './MyInterface';

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

我的继承类.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 的 typings 中生效?

更新更多详情:

情况是我有两个项目:

  • 第一个项目是我生成库的地方,我将在这里发布到 npm,而 package.json 是我放置 typings 属性的地方,该属性链接到由 tsc -d 命令生成的 mydefinition.d.ts 文件。

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

包含这两个项目的链接以及另一个用于场景的链接:

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

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

重现问题的方法:

  • 克隆此仓库: https://github.com/jvitor83/test-typings-packagejson

  • 执行 'npm install',用 VSCode 打开,并进入文件 'src/test.ts'。

答案#1

解决方案是:

1 - 添加一个单独的文件 'index.ts',用于导出所有其他文件。

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

2 - 在构建过程中添加两个文件的编译/转译(一个用于声明,另一个用于单个 JS 文件 [在 tsc 编译器中不带 property])

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();

相关文章