从typescript中获取内部javascript文件

Alo*_*lon 5 javascript typescript

我的项目中有一个js文件,我需要从ts文件中获取该文件.

js文件路径是"javascript/jsToConsume.js".

ts文件路径是"typescript/client.ts"

我在路径"typings/internal/jsToConsume.d.ts"中添加了一个声明文件,其内容如下:

declare namespace jsToConsume{
    export function func1(): void;
}
Run Code Online (Sandbox Code Playgroud)

在我的client.ts中我尝试使用它:

///<reference path="../typings/internal/jsToConsume.d.ts" />

import * as jsToConsume from '../javascript/jsToConsume'
Run Code Online (Sandbox Code Playgroud)

但是'../javascript/jsToConsume'标记为红线,我收到以下错误:

TS2307:找不到模块'../javascript/jsToConsume'

BTW代码运行完美,它只是一个TSC错误.

的JavaScript/jsToConsume.js:

function func1(){
    return "Hello World";
}
exports.func1 = func1;
Run Code Online (Sandbox Code Playgroud)

任何帮助将深表感谢!

the*_*obG 5

如果你通过了--allowJs国旗为true你的tsconfig.json,它告诉打字稿编译器来编译JavaScript文件也是如此.因此,将此标志设置为true,TypeScript将了解您在JavaScript文件中定义的模块,并且您不需要使用声明文件做任何额外的诡计.

因此,示例tsconfig.json文件可能如下所示:

{
  "compilerOptions": {
    "allowJs": true
    "module": "commonjs",
    "noImplicitAny": true,
    "target": "es6"
  },
  "exclude": [
    "node_modules"
  ]
}
Run Code Online (Sandbox Code Playgroud)

(https://www.typescriptlang.org/docs/handbook/compiler-options.html)

当然,配置文件完全取决于您的项目,但您只需添加"allowJS": true一个"compilerOptions".

注意:从TypeScript 1.8开始提供此功能

相关的发行说明如下:

https://www.typescriptlang.org/docs/release-notes/typescript-1.8.html#including-js-files-with---allowjs

- 编辑 -

为了回应关于要求类型以及内部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
Run Code Online (Sandbox Code Playgroud)

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';
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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_;
Run Code Online (Sandbox Code Playgroud)

因此,在从模块导入单个成员和默认值时,只需为每个成员提供所需的类型.然后,您可以在使用时为模块的公共导出提供接口import * as ....

注意 但是你必须有一个很好的理由,为什么你不想只是将你的JS文件更改为TS.想一想您希望文件的类型,并且您可以控制它们,因为它们是项目的内部,因此听起来就像TS存在的确切用例.您无法控制外部模块,因此您可以构建声明文件以创建用于与库交互的接口.如果您决定向JavaScript添加类型,那么您可以通过将其设置为TypeScript来实现.