我有一个TypeScript类,它是npm包的一部分。为了维护,我将该类分解为多个类,并通过继承建立了最终的导出类。我认为这与我的问题无关,但我认为最好公开这些信息。我在ChildClass.ts
中定义了这样的类:
export default ChildClass extends ParentClass{…}
Tsc的{build}为outDir
。
package.json
文件具有属性"main": "build/ChildClass.js"
同时使用npm link
和npm pack
,我可以部署该包并在TypeScript演示包中毫无问题地使用它。但是,如果我尝试在JavaScript演示中使用该包,则
const ChildClass = require('my-package')
const childClass = new ChildClass()
我得到了错误
Cannot use 'new' with an expression whose type lacks a call or construct signature.ts(2351)
如果我通过添加new
来更改.default
语句,则:
const childClass = new ChildClass.default()
有效。我通过查看已编译的Javascript来解决这个问题。不得不使用.default
使我感到震惊,这是我期望我的程序包的(假设的)JavaScript使用者知道的不合理的事情。我还发现,如果我避免使用export default
而只使用export
,则该程序包的工作更可预测,所以我就是这样做的。现在我可以使用
const {ChildClass} = require('my-package')
const childClass = new ChildClass()
和类似的语法
import {ChildClass} from 'my-package'
const childClass = new ChildClass()
在打字稿中。
仍然,我想知道这个神奇的.default
属性是什么以及为什么需要它。
此外,我发现的所有其他有关此错误的参考文献似乎都与我所看到的无关。我认为记录此文档可能会帮助遇到类似错误的其他人。
答案 0 :(得分:2)
ECMAScript语言规范specified中,导出的width: 100%;
名称仅为* {
box-sizing: border-box;
position: relative;
}
.stepProgressBarContainer {
width: 100%;
}
.stepProgressBarContainer .stepProgessBar {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0px;
}
.stepProgressBarContainer .stepProgessBar li {
list-style-type: none;
position: relative;
text-align: center;
display: block;
width: 100%;
}
.stepProgressBarContainer .stepProgessBar li:before {
content: '';
display: block;
width: 18px;
height: 18px;
-moz-border-radius: 9px;
-webkit-border-radius: 9px;
border-radius: 9px;
background: #fff;
border: 4px solid #ccc;
box-sizing: border-box;
text-align: center;
margin: 0px auto 7.5px auto;
}
.stepProgressBarContainer .stepProgessBar li:after {
content: '';
position: absolute;
width: 100%;
height: 4px;
background-color: #ddd;
top: 7px;
left: -50%;
z-index: -1;
}
.stepProgressBarContainer .stepProgessBar li:first-child:after {
content: none;
}
.stepProgressBarContainer .stepProgessBar li:last-child:before {
border-color: #2266e3;
}
.stepProgressBarContainer .stepProgessBar li.completed +:after {
background: linear-gradient(0deg, #2266e3, #2266e3);
}
.stepProgressBarContainer .stepProgessBar li.completed:before {
content: '\E73E';
border: 0;
background: #2266e3;
content: "\f007";
font-family: 'Font Awesome\ 5 Free';
font-weight: 900;
}
。因此,您可以将其视为名为<div class="stepProgressBarContainer">
<ul class="stepProgessBar">
<li class="completed">Step 1 2 3 4 5 5</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
</ul>
</div>
的普通导出。
将ES6模块编译为CommonJS仅具有一个事实标准,因为ECMAScript语言规范从未对此提及。目前,编译器(TypeScript和Babel)仅将所有导出内容放到export default
,在这里默认的导出不再特殊。
仅当消费者也了解上述“标准”(例如TypeScript,Babel和Webpack)时,他们才会为您将"default"
语句转换为"default"
。当然,Node.js分别处理CommonJS和ES6模块,而不是这样做。
(实际上,这更加复杂,因为Babel将module.exports
和import ChildClass from 'my-package
混合在一起,现代模块的消费者必须同时尝试这两者)
TypeScript具有special syntax const ChildClass = require('my-package').default
,可以与传统的CommonJS使用者一起使用(它不在JavaScript中)。如果将import DefaultExport from 'some-package'
更改为import * as AllExports from 'some-package
,它应该可以按预期工作。