ktr*_*yak 199 node-modules typescript
我读了TypeScript 模块解析的工作原理.
我有以下存储库:ts-di.编译目录结构后如下:
??? dist
? ??? annotations.d.ts
? ??? annotations.js
? ??? index.d.ts
? ??? index.js
? ??? injector.d.ts
? ??? injector.js
? ??? profiler.d.ts
? ??? profiler.js
? ??? providers.d.ts
? ??? providers.js
? ??? util.d.ts
? ??? util.js
??? LICENSE
??? package.json
??? README.md
??? src
? ??? annotations.ts
? ??? index.ts
? ??? injector.ts
? ??? profiler.ts
? ??? providers.ts
? ??? util.ts
??? tsconfig.json
Run Code Online (Sandbox Code Playgroud)
在我的package.json中,我写道"main": "dist/index.js".
在Node.js中一切正常,但TypeScript:
import {Injector} from 'ts-di';
Run Code Online (Sandbox Code Playgroud)
无法找到模块'ts-di'的声明文件.'/path/to/node_modules/ts-di/dist/index.js'隐式具有'任意'类型.
然而,如果我导入如下,那么一切正常:
import {Injector} from '/path/to/node_modules/ts-di/dist/index.js';
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
ktr*_*yak 224
另外两种方式,当一个模块不是你的 - 只需尝试安装它来自@types:
npm install -D @types/module-name
Run Code Online (Sandbox Code Playgroud)
或者,如果安装错误 - 尝试重写import为require:
// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');
Run Code Online (Sandbox Code Playgroud)
Ret*_*sam 161
如果您要导入的第三方模块'foo'没有提供任何类型,无论是在库本身,还是在@types/foo包中(从DefinitelyTyped存储库生成),那么您可以通过在模块中声明模块来消除此错误.d.ts文件:
// foo.d.ts
declare module 'foo';
Run Code Online (Sandbox Code Playgroud)
然后当你导入foo它时,只需键入即可any.
或者,如果你想要自己打字,你也可以这样做:
// foo.d.ts
declare module 'foo' {
export function getRandomNumber(): number
}
Run Code Online (Sandbox Code Playgroud)
然后这将正确编译:
import { getRandomNumber } from 'foo';
const x = getRandomNumber(); // x is inferred as number
Run Code Online (Sandbox Code Playgroud)
您不必为模块提供完整的输入,只需足够用于您实际使用的位(并且需要正确的输入),因此如果您使用相当少量的API,则特别容易.
另一方面,如果您不关心外部库的类型并希望将所有没有输入的库导入为any,则可以将其添加到.d.ts文件中:
declare module '*';
Run Code Online (Sandbox Code Playgroud)
这样做的好处(也就是缺点)是你可以导入任何东西,TS会编译.
ktr*_*yak 79
当你正在寻找了两天,发现它像这样的感受:只是删除.js从"main": "dist/index.js"在package.json,一切工作正常!
"main": "dist/index",
Run Code Online (Sandbox Code Playgroud)
UPD:这个答案是相对的,如果你有自己的npm包,如果没有 - 请参阅下面的答案.
如果以上回答没有解决您的进口模块,尝试只需添加typings在package.json:
"main": "dist/index",
"typings": "dist/index",
Run Code Online (Sandbox Code Playgroud)
当然,这里是文件夹dist- 它存储模块的文件.
Lir*_*n H 59
如果您需要快速修复,只需在导入之前添加以下内容即可:
// @ts-ignore
Run Code Online (Sandbox Code Playgroud)
Mar*_*ett 38
对于阅读本文的其他人,请尝试将您的 .js 文件重命名为 .ts
编辑:您还可以添加"allowJs": true到您的 tsconfig 文件。
Mar*_*ski 29
TypeScript基本上是实现规则并向代码添加类型,以使其更加清晰和准确,因为Javascript中缺少约束.TypeScript要求您描述数据,以便编译器可以检查您的代码并查找错误.如果您使用不匹配的类型,如果您超出范围或尝试返回其他类型,编译器将通知您.因此,当您使用带有TypeScript的外部库和模块时,它们需要包含描述该代码中类型的文件.这些文件称为带扩展名的类型声明文件d.ts.npm模块的大多数声明类型都已编写,您可以使用它们包含它们npm install @types/module_name(其中module_name是您希望包含其类型的模块的名称).
但是,有些模块没有它们的类型定义,为了使错误消失并使用导入模块import * as module_name from 'module-name',typings在项目的根目录中创建一个文件夹,在里面创建一个带有模块名称的新文件夹,并在其中文件夹创建一个module_name.d.ts文件并写入declare module 'module_name'.在此之后就到你的tsconfig.json文件,并添加"typeRoots": [ "../../typings", "../../node_modules/@types"]在compilerOptions(与你的文件夹正确的相对路径),让打字稿知道在哪里可以找到你的库和模块的类型定义和新的属性添加"exclude": ["../../node_modules", "../../typings"]到文件中.以下是tsconfig.json文件的示例:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
"sourceMap": true,
"outDir": "../dst/",
"target": "ESNEXT",
"typeRoots": [
"../../typings",
"../../node_modules/@types"
]
},
"lib": [
"es2016"
],
"exclude": [
"../../node_modules",
"../../typings"
]
}
Run Code Online (Sandbox Code Playgroud)
通过这样做,错误将消失,您将能够坚持最新的ES6和TypeScript规则.
小智 25
typings.d.ts只需在项目的根目录中创建一个名为的文件即可。在此文件中只需添加declare module <module_name>. 这里,module_name可以是您要导入的任何模块的名称。最后,打开tsconfig.json文件并将该文件包含typings.d.ts在名为 的数组中include array。
// typings.d.ts
declare module 'abc-module';
// tsconfig.json
{
...
"include": [
"src", "typings.d.ts"
]
}
// BOOM, Problem solved!!!
Run Code Online (Sandbox Code Playgroud)
该技术为您的模块提供了名为“any”的类型。欲了解更多信息:https://medium.com/@steveruiz/using-a-javascript-library-without-type-declarations-in-a-typescript-project-3643490015f3
Bin*_* Ho 20
这对我有用。
// modules.d.ts
declare module 'my-module';
Run Code Online (Sandbox Code Playgroud)
// tsconfig.json
{
...
"include": [
...
"src", "modules.d.ts"
]
}
Run Code Online (Sandbox Code Playgroud)
// Import
import * as MyModule from 'my-module'
...
const theModule = MyModule()
...
Run Code Online (Sandbox Code Playgroud)
San*_*tos 15
这就是我让它工作的方式。
就我而言,我使用了一个没有定义类型的库:react-mobile-datepicker
A。里面创建一个文件夹/src。就我而言,我使用了这条路径:/src/typings/。
b. 创建一个.d.ts文件。以我为例:/src/typings/react-mobile-datepicker.d.ts
C。我使用以下代码来扩展其属性并使其类型安全:
declare module 'react-mobile-datepicker' {
class DatePicker extends React.Component<DatePickerProps, any> {}
interface DatePickerProps {
isPopup?: boolean;
theme?: string;
dateConfig?: DatePickerConfig;
}
export interface DatePickerConfig {
prop1: number;
pro2: string;
}
export default DatePicker;
}
Run Code Online (Sandbox Code Playgroud)
d. 像使用第 3 方库时通常执行的操作一样导入您的类型。
import DatePicker, { DatePickerConfig, DatePickerConfigDate } from 'react-mobile-datepicker';
Run Code Online (Sandbox Code Playgroud)
e. 更改tsconfig.json并添加这段代码:
{
"compilerOptions": {
//...other properties
"typeRoots": [
"src/typings",
"node_modules/@types"
]
}}
Run Code Online (Sandbox Code Playgroud)
我用作来源的文章的链接:
https://templecoding.com/blog/2016/03/31/creating-typescript-typings-for-existing-react-components
https://www.credera.com/insights/typescript-adding-custom-type-definitions-for-existing-libraries
不幸的是,我们无法控制包编写者是否会为声明文件烦恼。我倾向于做的是有一个文件,index.d.ts其中将包含来自各种包的所有丢失的声明文件:
索引.d.ts:
declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';
Run Code Online (Sandbox Code Playgroud)
并在您的tsconfig.js:
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx",
"index.d.ts" // this
]
Run Code Online (Sandbox Code Playgroud)
小智 6
我使用带有用打字稿编写的反应应用程序的节点模块时遇到了同样的问题。该模块已成功安装使用npm i --save my-module. 它是用 javascript 编写的并导出一个Client类。
和:
import * as MyModule from 'my-module';
let client: MyModule.Client = new MyModule.Client();
Run Code Online (Sandbox Code Playgroud)
编译失败并显示错误:
Could not find a declaration file for module 'my-module'.
'[...]/node_modules/my-module/lib/index.js' implicitly has an 'any' type.
Try `npm install @types/my-module` if it exists or add a new declaration (.d.ts) file containing `declare module 'my-module';`
Run Code Online (Sandbox Code Playgroud)
@types/my-module不存在,所以我my-module.d.ts在my-module导入的文件旁边添加了一个文件,并带有建议的行。然后我得到了错误:
Namespace '"my-module"' has no exported member 'Client'.
Run Code Online (Sandbox Code Playgroud)
如果我在 js 应用程序中使用它,客户端实际上已导出并正常工作。此外,上一条消息告诉我编译器正在查找正确的文件(/node_modules/my-module/lib/index.js在my-module/package.json "main"element 中定义)。
我通过告诉编译器我不关心隐式解决了这个问题any,也就是说,我设置为文件false的以下行tsconfig.json:
"noImplicitAny": false,
Run Code Online (Sandbox Code Playgroud)
一个简单的修复:
// example.d.ts
declare module 'foo';
Run Code Online (Sandbox Code Playgroud)
如果你想声明一个对象的接口(推荐用于大型项目),你可以使用:
// example.d.ts
declare module 'foo'{
// example
export function getName(): string
}
Run Code Online (Sandbox Code Playgroud)
如何使用它?简单的..
const x = require('foo') // or import x from 'foo'
x.getName() // intellisense can read this
Run Code Online (Sandbox Code Playgroud)
小智 6
检查"tsconfig.json"文件的编译选项"include"和"exclude". 如果不存在,只需通过通知您的根目录来添加它们。
// tsconfig.json
{
"compilerOptions": {
...
"include": [
"src",
],
"exclude": [
"node_modules",
]
}
Run Code Online (Sandbox Code Playgroud)
"*.spec.ts"我只是通过从 中删除扩展语句来解决我的愚蠢问题"exclude",因为当"import"在这些文件中包含 时,总是存在问题。
解决方案:您所要做的就是编辑您的 TypeScript 配置文件tsconfig.json并添加一个新的键值对作为
"compilerOptions": {
"noImplicitAny": false
}
Run Code Online (Sandbox Code Playgroud)
这种方式对我有用:
1.在声明文件中添加自己的声明,例如index.d.ts(可能在项目根目录下)declare module 'Injector';
Run Code Online (Sandbox Code Playgroud)
2.将您的index.d.ts添加到tsconfig.json
{
"compilerOptions": {
"strictNullChecks": true,
"moduleResolution": "node",
"jsx": "react",
"noUnusedParameters": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports":true,
"target": "es5",
"module": "ES2015",
"declaration": true,
"outDir": "./lib",
"noImplicitAny": true,
"importHelpers": true
},
"include": [
"src/**/*",
"index.d.ts", // declaration file path
],
"compileOnSave": false
}
Run Code Online (Sandbox Code Playgroud)
-编辑:模块名称周围需要用引号引起来
小智 5
如果您已经安装了该模块但仍然收到错误,一个简短而有效的解决方案是通过在该行上方添加以下行来忽略错误消息
// @ts-ignore: Unreachable code error
Run Code Online (Sandbox Code Playgroud)
@ktretyak 和 @Retsam 的答案是正确的,但我想添加一个完整的实时示例以及我必须做的事情:
错误:
错误 TS7016 (TS) 找不到模块“react-region-select”的声明文件。
'C:/Repo/node_modules/react-region-select/lib/RegionSelect.js' 隐式具有 'any' 类型。
尝试
npm i --save-dev @types/react-region-select它是否存在或添加包含“declare module”的新声明(.d.ts)文件
运行npm i --save-dev @types/react-region-select出现错误:
npm 错误!代码 E404
npm 错误!404 未找到 - GET https://registry.npmjs.org/@types%2freact-region-select - 未找到
npm 错误!404 '@types/react-region-select@latest' 不在 npm 注册表中。
npm 错误!第404章 你应该骚扰作者发布它(或者自己使用这个名字!)
npm 错误!404 请注意,您还可以从 npm tarball、文件夹、http url 或 git url 安装。
鉴于create-react-app创建了一个名为react-app-env.d.ts我试图放入declare module 'react-region-select';其中的文件,但我仍然收到错误。
src然后我在名为 的文件夹中创建了一个新文件夹typings,并创建了一个名为 的文件react-region-select.d.ts。我在那里声明了该模块,如下所示:
declare module 'react-region-select';
Run Code Online (Sandbox Code Playgroud)
这样做之后,错误消失了,我可以像文档所述那样导入它:
import RegionSelect from "react-region-select";
Run Code Online (Sandbox Code Playgroud)
https://github.com/casavi/react-region-select
小智 5
就我而言,解决此问题的 3 种不同方法均无效。一旦你在 package.json 中将“type”设置为“module”,那么它将遵循 ES Module 而不是 CommonJS 语法。我能够根据我的 package.json 设置使用 ES 模块语法来解决这个问题。
import ws from 'ws'
export const create = (/** @type {string} */ accessToken) => {
const WebSocket = ws;
return new WebSocket(endpoint, accessToken, sslOptions);
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以在“ws”模块中使用 WebSocket 类。这是节点模块的示例,但基本上您可以在其中放置任何类型的节点模块和函数。
下面这些对我不起作用:
npm install -D @types/module-nameconst foo = require('module-name');// index.d.ts
declare module 'foo';
Run Code Online (Sandbox Code Playgroud)
"noImplicitAny": true,
"allowJs": true
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
244337 次 |
| 最近记录: |