Consume javascript internal file from typescript

I have a js file in my project that I need to use from a ts file.

The js file path is "javascript / jsToConsume.js".

Ts file path "typescript / client.ts"

I added the declaration file to the path "typings / internal / jsToConsume.d.ts", the contents of which are as follows:

declare namespace jsToConsume{ export function func1(): void; } 

In my client.ts, I'm trying to use it:

 ///<reference path="../typings/internal/jsToConsume.d.ts" /> import * as jsToConsume from '../javascript/jsToConsume' 

But '../javascript/jsToConsume' marked with a red line, and I get the following error:

TS2307: Cannot find module '../javascript/jsToConsume'

By the way, the code works flawlessly, it's just a TSC error.

JavaScript / jsToConsume.js:

 function func1(){ return "Hello World"; } exports.func1 = func1; 

Any help would be greatly appreciated!

+5
source share
2 answers

If you pass the --allowJs flag as true in tsconfig.json , it tells the TypeScript compiler to also compile JavaScript files. Therefore, if this flag is set to true, TypeScript will know about the modules that you defined in your JavaScript files, and you won’t need to do unnecessary tricks with the declaration files.

Therefore, an example tsconfig.json file might look like this:

 { "compilerOptions": { "allowJs": true "module": "commonjs", "noImplicitAny": true, "target": "es6" }, "exclude": [ "node_modules" ] } 

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

Of course, the configuration file will depend entirely on your project, but you just add "allowJS": true as one of your "compilerOptions" .

Note. It is available as TypeScript 1.8.

Relevant release notes are here:

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

- CHANGE -

In response to comments about type requirements along with your internal JS import, I came up with the following. However, if you run into this problem in order to add types to your JavaScript modules, I would just suggest converting the file to TypeScript and type all your export with a minimum minimum (actually, looking back at this edit, this seems really unnecessary if it’s absolutely impossible to any reason to convert JS to TS). But anyway...

You still go through "allowJS": true in your tsconfig.json , but you can create interfaces for the necessary JavaScript modules and then import them into your TS file. Below is an example: with a JS file and TS file a little more to show the possibilities:

Folder structure

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

So, when importing individual elements and default values ​​from a module, simply specify each type you want. You can then provide an interface for publicly exporting the module by using import * as ...

Note But you must have a really good reason why you don't want to just change your JS files to TS. Think for a moment that you want types for your files, and you control them because they are internal to your project, so this sounds like a usage example for why TS exists. You cannot manage external modules, so create declaration files to create an interface for interacting with the library. If you decide to add types to your JavaScript, you can do this by making it TypeScript.

+5
source

For external modules, the problem is on the line:

 import * as jsToConsume from '../javascript/jsToConsume' 

The code will even be without it, because you have a link:

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

The usual way to use an external module has only one line ( https://www.typescriptlang.org/docs/handbook/modules.html ):

 import * as jsToConsume from 'jsToConsume'; 

And even better, rename the namespace to the module:

 declare module jsToConsume{...} 

This was for external modules.


But if you only have internal modules, it is better to use modules without a namespace, simply:

 export function func1(): void; 

Then you can use it like:

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

or

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

Source: https://habr.com/ru/post/1258370/


All Articles