简体   繁体   English

为外部 js nodejs package 编写 typescript 声明文件,没有类型信息

[英]Writing a typescript declaration file for an external js nodejs package, without type info

I'm writing a node js typescript library (for use in cli app context) which has a dependency on a js library jinxed, which has no typescript type declarations.我正在编写一个节点 js typescript 库(用于 cli 应用程序上下文),它依赖于一个 js 库 jinxed,它没有 typescript 类型声明。 I have been following information at Typescript declaration files我一直在关注 Typescript 声明文件中的信息

jinxed is a simple library that currently exports a single function via module.exports {... }, it is not intended to be the sole export from the library, (since it will be expanded in the future). jinxed是一个简单的库,目前通过 module.exports {... } 导出单个 function,它不打算作为库的唯一导出,(因为将来会扩展它)。 So the exported function is a member of the export object.所以导出的 function 是导出 object 的成员。

The problem is how do I consume this within a typescript library.问题是我如何在 typescript 库中使用它。 After reading all the typescript declaration documentation, this is still not clear to me how to do this.在阅读了所有 typescript 声明文档之后,我仍然不清楚如何做到这一点。

The first problem to solve is which declaration template to pick from Typescript declaration file templates .首先要解决的问题是从Typescript 声明文件模板中选择哪个声明模板

I decided that the appropriate template to use to enable consuming jinxed from typescript is module.d.ts (I stand to be corrected though).我决定使用适当的模板来启用从 typescript 中产生的 jinxed 是module.d.ts (尽管我需要更正)。

So my client typescript library (widget) looks like this:所以我的客户 typescript 库(小部件)看起来像这样:

widget/
  lib/
    externalTypes/
      jinxed/
        index.d.ts
    index.ts

So the above shows me defining a type file for the external dependency jinxed according to the instructions in the template file;所以上面显示了我根据模板文件中的说明为外部依赖项定义了一个类型文件; ie create a folder whose name matches the name of the external dependency and place an index.d.ts file inside it.即创建一个名称与外部依赖项名称匹配的文件夹,并在其中放置一个 index.d.ts 文件。

widget/lib/externalTypes/jinxed/index.d.ts:小部件/lib/externalTypes/jinxed/index.d.ts:

export function functify(obj: any): string;导出 function 函数(obj:任意):字符串;

On the consuming side;在消费方面; ie inside my index.ts file (widget/lib/index.ts):即在我的 index.ts 文件中(小部件/lib/index.ts):

/// <reference types="./externalTypes/jinxed" />

import jinxed = require('jinxed');

const TestObject:any = {
  name: 'dvorak',
  occ: 'watchman'
};

jinxed.functify(TestObject);

[PS: I have also tried: [PS:我也试过:

let jinxed = require('./externalTypes/jinxed');让 jinxed = require('./externalTypes/jinxed'); (... but this just results in an error about using the require statment) (...但这只会导致有关使用 require 语句的错误)

] ]

But when compiled results in the following error message:但是编译时会出现以下错误消息:

ERROR in /Users/User/dev/github/js/widget/lib/index.ts./lib/index.ts [tsl] ERROR in /Users/User/dev/github/js/widget/lib/index.ts./lib/index.ts [tsl] 中的错误

/Users/User/dev/github/js/widget/lib/index.ts(4,25) TS7016: Could not find a declaration file for module 'jinxed'. /Users/User/dev/github/js/widget/lib/index.ts(4,25) TS7016:找不到模块“jinxed”的声明文件。 '/Users/User/dev/github/js/widget/node_modules/jinxed/index.js' implicitly has an 'any' type. '/Users/User/dev/github/js/widget/node_modules/jinxed/index.js' 隐含了一个 'any' 类型。

(Apologies for the error message looking a bit ugly, formatting issues) (对于错误消息看起来有点难看,格式问题表示歉意)

[ [

And for the sake of completeness, the content of jinxed is as follows:并且为了完整起见,jinxed的内容如下:

'use strict';

function functify (obj) {
  return JSON.stringify(obj, (key, val) => {
    return (typeof val === 'function') ? '_function_' : val;
  });
}

module.exports = {
  functify: functify
}

] ]

The error message is indicating that it can't find the declaration file for jinxed, but I have used the错误信息表明它找不到jinxed的声明文件,但我使用了

 /// <reference...

to specify the type file to use, so I don't know what the problem is.指定要使用的类型文件,所以我不知道问题是什么。

The dependencies in widget packaage.json is as follows: widget package.json中的依赖如下:

  "dependencies": {
    "@types/ramda": "^0.26.19",
    "jinxed": "0.0.1",
    "ramda": "^0.26.1",
    "xpath": "0.0.27"   },

The tsconfig file is: tsconfig 文件是:

{
  "compilerOptions": {
    "allowJs": true,
    "alwaysStrict": true,
    "module": "commonjs",
    "moduleResolution": "Node",
    "noImplicitAny": true,
    "sourceMap": true,
    "strictNullChecks": true,
    "target": "es5",
    "types": [],
    "lib": [
      "es5",
      "es2015",
      "es6",
      "dom"
    ]
  },
  "include": [
    "lib/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

The "main" entry in package.json is: package.json 中的“主要”条目是:

"main": "./lib/index.ts", “主”:“./lib/index.ts”,

Also, I would like to know if the way I have structured external type dependencies seems reasonable.另外,我想知道我构建外部类型依赖项的方式是否合理。 IE, let's say, I am trying to consume another external js library in a similar way to that illustrated above for jinxed; IE,比方说,我正在尝试以与上述 jinxed 类似的方式使用另一个外部 js 库; I would assume, that I would create another folder under externalTypes that matches the name of that dependency and populate it with its own index.d.ts.我会假设,我会在 externalTypes 下创建另一个与该依赖项名称匹配的文件夹,并用它自己的 index.d.ts 填充它。 Is that correct or am I barking up the wrong tree?这是正确的还是我在吠叫错误的树?

EDIT: (I found the solution to this problem via this issue , but I don't really userstand this.编辑:(我通过这个问题找到了解决这个问题的方法,但我并不真正理解这一点。

In the index.d.ts, I have updated it to be as follows:在 index.d.ts 中,我已将其更新为:

declare module 'jinxed' {
  export function functify(obj: any): string;
}

... and this does actually work. ...这确实有效。

However, I don't understand the declare module statement, in particular, why the names jinxed is inside quotes (remove the quotes and you get an error: TS7016: Could not find a declaration file for module 'jinxed').但是,我不明白declare module语句,特别是为什么jinxed的名称在引号内(删除引号会出现错误:TS7016:找不到模块'jinxed'的声明文件)。 So far I have not found the correct typescript template that this corresponds to, so I can't get a good explanation of why this works.到目前为止,我还没有找到与之对应的正确 typescript 模板,所以我无法很好地解释为什么会这样。

It looks like you found the answer to your original question, but I thought I'd share some resources regarding your second question.看起来您找到了原始问题的答案,但我想我会分享一些关于您的第二个问题的资源。 From the typescript docs: Ambient Modules来自 typescript 文档: 环境模块

In Node.js, most tasks are accomplished by loading one or more modules.在 Node.js 中,大多数任务都是通过加载一个或多个模块来完成的。 We could define each module in its own.d.ts file with top-level export declarations, but it's more convenient to write them as one larger.d.ts file.我们可以使用顶级导出声明在其自己的.d.ts 文件中定义每个模块,但将它们写成一个更大的.d.ts 文件更方便。 To do so, we use a construct similar to ambient namespaces, but we use the module keyword and the quoted name of the module which will be available to a later import.为此,我们使用类似于环境命名空间的构造,但我们使用模块关键字和模块的引用名称,这些名称将可用于以后的导入。

The declare module are language keywords, and the string is the name of the module you're importing. declare module是语言关键字,字符串是您要导入的模块的名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Typescript 外部声明文件 npm package - 构造函数 - Typescript declaration file for an external npm package - constructor 编写声明文件:打字稿 - Writing a declaration file: typescript 如何在 TypeScript (Node.js) 包中包含全局文件类型声明 - How to include a global file type declaration in a TypeScript (Node.js) package 如何在Typescript中粗略导入.js库而不进行类型声明? - How to roughly import .js libraries without type declaration in typescript? 如何在Node.js中使用打字稿声明文件要求外部js库 - How to require an external js library in Node.js with a typescript declaration file 用于打字的TypeScript外部节点模块声明文件 - TypeScript External Node Module Declaration File For Typings npm 包中的自定义 TypeScript 声明文件不起作用 - Custom TypeScript declaration file in npm package not working 如何将声明文件添加到依赖于外部声明文件的程序包中 - How to add declaration file to package that depends on external declaration file 在打字稿中,如何使用声明文件从外部JS库继承 - In typescript, how can I inherit from an external JS library using a declaration file 导入到Node.js TypeScript文件中的包无法被命名空间节声明识别吗? - Package imported into Node.js TypeScript file not recognized by namespace section declaration?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM