为未经类型定义的npm模块创建TypeScript自定义声明文件

63

我正在将一个名为shiitake的React组件从npm导入到我的TypeScript项目中。该库没有TypeScript声明,因此我打算自己写一个。声明文件如下所示(可能不完整,但不用太担心):

import * as React from 'react';

declare module 'shiitake' {

    export interface ShiitakeProps {
        lines: number;
    }

    export default class Shiitake extends React.Component<ShiitakeProps, any> { 
    }
}

我已经将这个内容放在./typings/shiitake.d.ts文件中,在VS Code上,我看到以下错误:

[ts] 增加的模块名无效。 模块“shiitake”解析为位于“d:/dev/foo/foobar.foo.Client.Web/node_modules/shiitake/dist/index.js”的未标记模块,无法增强。

在使用方面,即使使用了上述声明(因为我已经打开了noImplicitAny编译器开关),我仍然会收到相同的错误消息:

/// <reference path="../../../../typings/shiitake.d.ts" />
import * as React from 'react';
import Shiitake from 'shiitake';
[ts] 找不到模块“shiitake”的声明文件。'd:/dev/foo/foobar.foo.Client.Web/node_modules/shiitake/dist/index.js'隐式具有“any”类型。 获取此类型模块的声明文件的标准方法是通过@types/方式,这种方法有效。但是,我无法让自定义类型起作用。有什么想法吗?
3个回答

170
声明 declare module 'shiitake'; 应该在全局范围内,也就是非模块的顶层声明(其中模块是具有至少一个顶级 importexport 的文件)。
在模块中形式为declare module '...' { }的声明是一个扩展。更多详情请参见 Typescript 模块扩展
因此,您希望这个文件看起来像这样:
declare module 'shiitake' {

    import * as React from 'react';

    export interface ShiitakeProps {
        lines: number;
    }

    export default class Shiitake extends React.Component<ShiitakeProps, any> { 
    }
}

29
非常感谢你的帮助。对我来说,问题在于“import”语句位于模块外部而不是内部。 - dbellizzi
5
我希望我能给这个点赞十次。昨天我花了好几个小时在这上面。我真的希望 TypeScript 的文档能对此更好些。 - Benjamin Riggs
3
这个问题太傻了,而且所给的警告非常不清楚。VSCode让我出乱子了。 - Nate Glenn
@dudewad请检查该帖子的用户名,看起来最多是自我剽窃(这在这里被禁止了吗?) - Robert Columbia
谢谢!我的导入在模块声明之外。 - silvenon

7

根据我的经验,如果一个定义文件中有任何在模块定义之外声明的导出或导入,它将会失败。如果你使用带有自动导入功能的IDE,请注意!


4

今天我也遇到了同样的问题。

事实证明我将导出的接口粘贴到模块声明之外。 我使用的类型文件模板在文件末尾包含了私有接口。

因此,我的导出接口是在模块声明之外声明的。 这让 TypeScript 编译器感到困惑。

一旦我将接口移动到模块边界内,一切都解决了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接