簡體   English   中英

從typescript中獲取內部javascript文件

[英]Consume internal javascript file from typescript

我的項目中有一個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;

任何幫助將深表感謝!

如果你通過了--allowJs標志作為true在你tsconfig.json ,它告訴打字稿編譯器來編譯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開始提供此功能

相關的發行說明如下:

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

- 編輯 -

為了回應有關要求類型以及內部JS導入的評論,我提出了以下建議。 但是,如果在向JavaScript模塊添加類型時遇到這么多麻煩,我建議將文件轉換為TypeScript並至少輸入所有導出(實際上,回頭看這個編輯,這看起來真的沒必要,除非無論出於何種原因,將JS轉換為TS都是絕對不可能的。 但無論如何...

您仍然可以在tsconfig.json傳遞"allowJs": true ,但您可以為所需的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來實現。

對於外部模塊,問題在於:

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';

更好的是將名稱空間重命名為模塊:

declare module jsToConsume{...}

這是針對外部模塊的


但是如果你只有內部模塊,那么最好使用沒有命名空間的模塊,只需:

export function func1(): void;

然后你可以用它作為:

import {func1} from '../javascript/jsToConsume';

要么

 import * as someName from '../javascript/jsToConsume';
someName.func1();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM