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.