简体   繁体   English

遇到错误:如何从打字稿中正确使用已翻译并键入的打字稿npm模块?

[英]Getting errors: How can I properly consume my transpiled and typed typescript npm module from typescript?

I'm still giving a shot at typescript. 仍在尝试打字稿。 I've written a trivial "hello world" typescript module and published it to npm . 我编写了一个简单的“ hello world”打字稿模块,并将其发布到npm Really trivial, just does a default export: 确实很简单,只是执行默认导出:

export default function hello(target: string = 'World'): void
{
    console.log(`Hello, ${target} :-(`)
}

It is consumed perfectly well by node.js 0.10 -> 6. The module also has a proper "typings" property in package.json, pointing to an existing .d.ts file generated by tsc as explained in the official documentation : node.js 0.10-> 6可以很好地使用它。该模块在package.json中还具有适当的"typings"属性,指向tsc生成的现有.d.ts文件, 如官方文档中所述

export default function hello(target?: string): void;

However, I can't get it consumed by typescript code, neither in typescript 1.8 nor 2 : 但是,无论是打字稿1.8还是2,我都无法通过打字稿代码使用它:

import hello = require('hello-world-emo')

hello()
hello('Offirmo')

Transpiling with tsc or executing with ts-node both give the same error message: 使用tsc编译或使用ts-node执行都给出相同的错误消息:

TSError: ⨯ Unable to compile TypeScript
hello.ts (3,1): Cannot invoke an expression whose type lacks a call signature. (2349)

However, the generated .js works. 但是,生成的.js可以正常工作。 It just seems a typing issue. 似乎只是一个打字问题。 Using other import formats like import hello from 'hello-world-emo' doesn't work either. 使用其他导入格式(例如import hello from 'hello-world-emo'也不起作用。

What is typescript complaining ? 什么是打字稿抱怨? What did I miss ? 我错过了什么 ?

In case you want to inspect tsconfig , the module is here and I'm consuming it from here 如果您想检查tsconfig ,则模块在这里 ,我从这里使用它

The problem lies not in typescript but rather in ES6/CommonJS interop : there is no perfect matching between ES6 and CommonJS exports, especially for the ES6 "export default" , cf. 问题不在于打字稿,而在于ES6 / CommonJS互操作 :ES6和CommonJS导出之间没有完美的匹配, 尤其是ES6“默认导出” ,参见。 this article and this open issue on webpack . 本文webpack上的此未解决问题

Here the module code is written in ES6 using ES6 modules. 这里,模块代码是使用ES6模块在ES6中编写的。 The build procedure is: 生成过程为:

  1. transpile typescript to ES6 with tsc (typescript compiler) 使用tsc打字稿转换为ES6(打字稿编译器)
  2. transpile the ES6 code and bundle it with rollup +babel for: 转换ES6代码并将其与rollup + babel捆绑在一起,用于:
    • ES6@node4 / CommonJS (1st class citizen) ES6 @ node4 / CommonJS(一等公民)
    • ES5@node0.10 / CommonJS (for still widely used legacy) ES5@node0.10 / CommonJS(用于仍广泛使用的旧版)
    • ES5 / umd (for browsers) ES5 / umd(对于浏览器)

Node 4 (stable) being the 1st class citizen, the corresponding bundle (ES6@node4 / CommonJS) is exposed via the npm "main" entry. 节点4(稳定)是一等公民,相应的捆绑包(ES6 @ node4 / CommonJS)通过npm“ main”条目公开。 It has been converted to CommonJS as best as rollup could do, making it consumable by node 4 but no longer by typescript . 它已尽最大可能将其转换为CommonJS,使其可以在节点4上使用,而不再可以通过typescript来使用

Another option would have been to transpile to ES5/CommonJs with tsc , which adds special annotations for linking back CommonJS to ES6 modules . 另一个选择是使用tsc转换为ES5 / CommonJs, 它添加了特殊注释,用于将CommonJS链接回ES6模块 But then it's 1) no longer bundled 2) more roughly transpiled (not using ES6 features included in node 4) and 3) more hardly consumable by node 但是,这是1)不再捆绑2)更粗糙地转译(不使用节点4中包含的ES6功能)和3)节点几乎不消耗

A compromise solution : avoid the CommonJS / ES6 modules interop problem by not using export default but only named exports. 一个折衷的解决方案 :通过不使用export default而是仅使用命名的export default避免CommonJS / ES6模块互操作问题。 This mitigation technique only downside is for node 4 : 此缓解技术的唯一缺点是节点4:

  • ES6: import hello from '...' becomes import { hello } from '...' OK ES6: import hello from '...' import { hello } from '...'成为import hello from '...' import { hello } from '...'
  • node >=6: const hello = require('...') becomes const { hello } = require('...') OK 节点> = 6: const hello = require('...')成为const { hello } = require('...') OK
  • node <=4: var hello = require('...') becomes var hello = require('...').hello less elegant but acceptable 节点<= 4: var hello = require('...')变为var hello = require('...').hello 不太优雅但可以接受

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

相关问题 在 TypeScript 中写入时,如何看到 Deno 转译的 javascript? - How can I see Deno transpiled javascript when writing in TypeScript? 如何使用TypeScript在浏览器中使用NPM软件包? - How to consume NPM packages in the browser with TypeScript? 我的应用找不到从 NPM 注册表下载的 TypeScript package(找不到模块) - My app can't find my TypeScript package downloaded from the NPM registry (module not found) 如何使我的npm typescript模块在简单的Javascript项目中可用? - How to make my npm typescript module usable in simple Javascript project? 如何在 Typescript 中将类型化变量用作具有相同名称的类型? - How can I use typed variables as types with same name in Typescript? 如何在typescript定义中指定松散类型的对象文字? - How can I specify loosely typed object literal in typescript definition? 如何从 TypeScript 中的另一个模块引用现有类型? - How can I refer to an existing type from another module in TypeScript? 如何从Typescript模块导出2个项目 - How can I export 2 items from a Typescript Module 如何从TypeScript中的匿名对象轻松创建强类型对象? - How can I easily create a strongly typed object from an anonymous object in TypeScript? 如何从 Typescript 中类型化的 object 的属性值生成类型? - How can I generate a type from the properties values of a typed object in Typescript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM