我的项目中有一个js文件,我需要从ts文件中使用它。
js文件路径为“javascript / jsToConsume.js”。
ts文件路径是“typescript / client.ts”
我在路径“typings / internal / jsToConsume.d.ts”中添加了一个声明文件,其内容如下:
declare namespace jsToConsume{
export function func1(): void;
}
在我的client.ts中我尝试使用它:
///<reference path="../typings/internal/jsToConsume.d.ts" />
import * as jsToConsume from '../javascript/jsToConsume'
但'../javascript/jsToConsume'
标有红线,我收到以下错误:
TS2307:找不到模块'../javascript / jsToConsume'
BTW代码运行完美,这只是一个TSC错误。
的javascript / jsToConsume.js:
function func1(){
return "Hello World";
}
exports.func1 = func1;
任何帮助都将深表感谢!
答案 0 :(得分:5)
如果您在--allowJs
中将true
标记作为tsconfig.json
传递,它会告诉TypeScript编译器也编译JavaScript文件。因此,将此标志设置为true,TypeScript将了解您在JavaScript文件中定义的模块,并且您不需要使用声明文件做任何额外的诡计。
因此,示例tsconfig.json
文件可能如下所示:
{
"compilerOptions": {
"allowJs": true
"module": "commonjs",
"noImplicitAny": true,
"target": "es6"
},
"exclude": [
"node_modules"
]
}
(https://www.typescriptlang.org/docs/handbook/compiler-options.html)
当然,配置文件完全取决于您的项目,但您只需添加"allowJS": true
作为"compilerOptions"
之一。
注意:从TypeScript 1.8
开始提供相关发行说明如下:
- 编辑 -
在回应有关要求类型以及内部JS导入的评论时,我想出了以下内容。但是,如果在向JavaScript模块添加类型时遇到这么多麻烦,我建议将文件转换为TypeScript并至少输入所有导出(事实上,回头看这个编辑,这看起来真的没必要,除非无论出于何种原因,将JS转换为TS都是绝对不可能的。但无论如何......
您仍会在"allowJs": true
中传递tsconfig.json
,但您可以为所需的JavaScript模块创建界面,然后在TS文件中键入导入。下面提供了一个示例,JS文件和TS文件更加充实,以显示可能性:
文件夹结构
src
| - javascript
| | - jsToConsume.js
| - typescript
| | - client.ts
typings
| - typings.d.ts
tsconfig.json
<强> jsToConsume.js 强>
export const yourHair = (adjective) => {
return `Your hair is ${adjective}`;
}
export let jam = 'sweet';
export class AnotherClass {
constructor() {
this.foo = 'bar';
}
}
export default class Hungry {
constructor() {
this.hungry = true;
}
speak() {
return 'More cake please';
}
}
<强> typings.d.ts 强>
declare interface jsToConsumeModule {
yourHair: (adjective: string) => string;
jam: string;
AnotherClass: AnotherClassConstructor;
}
declare interface Hungry {
hungry: boolean;
speak: () => string;
}
declare interface HungryConstructor {
new (): Hungry;
}
declare interface AnotherClass {
foo: string;
}
declare interface AnotherClassConstructor {
new (): AnotherClass;
}
<强> client.ts 强>
import { yourHair as _yourHair_ } from './../javascript/jsToConsume';
const yourHair: (adjective: string) => string = _yourHair_;
import * as _jsToConsume_ from './../javascript/jsToConsume';
const jsToConsume: jsToConsumeModule = _jsToConsume_;
import _Hungry_ from './../javascript/jsToConsume';
const Hungry: HungryConstructor = _Hungry_;
因此,在从模块导入单个成员和默认值时,只需为每个成员提供所需的类型。然后,在使用import * as ...
时,您可以为模块的公共导出提供接口。
注意强> 但是你必须有一个很好的理由,为什么你不想只是将你的JS文件更改为TS。想一想您希望文件的类型,并且您可以控制它们,因为它们是项目的内部,因此听起来就像TS存在的确切用例。您无法控制外部模块,因此您可以构建声明文件以创建用于与库交互的接口。如果您决定在JavaScript中添加类型,那么可以通过将其设置为TypeScript来实现。
答案 1 :(得分:3)
对于外部模块,问题在于:
import * as jsToConsume from '../javascript/jsToConsume'
代码甚至没有它,因为你有参考:
///<reference path="../typings/internal/jsToConsume.d.ts" />
使用外部模块的正常方式只有一行(https://www.typescriptlang.org/docs/handbook/modules.html):
import * as jsToConsume from 'jsToConsume';
更好的是将命名空间重命名为module:
declare module jsToConsume{...}
这是针对外部模块的
但是如果你只有内部模块,最好使用没有命名空间的模块,只需:
export function func1(): void;
然后您可以将其用作:
import {func1} from '../javascript/jsToConsume';
或
import * as someName from '../javascript/jsToConsume';
someName.func1();