Typescript: Importing files other than TS modules

Created on 10 Apr 2015  Â·  92Comments  Â·  Source: microsoft/TypeScript

I've successfully been using SystemJS and TypeScript for a while now. I've been about to use the CommonJS syntax to easily import other TS modules, as well as other resources:

var OtherModule = require("./othermodule");
var Html = <string>require("./template.html!text");
require("./template.css!");

This is made possible by simply declaring the following function:

declare function require(name: string): any;

I'm now trying to do the same with the new ES6 syntax:

import { OtherModule } from "./othermodule";   // Works
import "./template.css!"; // Works
import Html from require("./template.html!text"); // Nope - 'Cannot find external module'

Of course I can do the same as before and declare and use 'require', but it'd be nice to keep it consistent. Perhaps assume that if an exclamation mark is in the path, then don't assume it's a TypeScript import?

Duplicate Suggestion

Most helpful comment

I'm coming to this as a newcomer, having only recently started playing with TypeScript as part of the Angular 2 developer preview. I presume there's going to be plenty more people who follow a similar path, so let me capture my impressions:

I appreciate the value of typing, but it's not my primary motivation for using TypeScript. I'm more interested in decorators and the fact that its the recommended language for Angular 2. My expectation was that typing would be an optional addition that I could gradually apply, but not that I'd have to immediately find or create type definitions for all my code and its dependencies.

Whatever the reason, throwing errors on valid JavaScript code is confusing when TypeScript is explicitly described as a superset of JavaScript. The first thing many people will do is load up an existing app and try to compile it. Getting a bunch of errors in response doesn't give a great first impression.

That "Cannot find external module" error is really bad. At first I thought it meant the compiler couldn't find the file on disk, so I spent quite a while moving it around and trying to figure out what was wrong. I also thought that it meant the compiler hadn't output anything. Compiler errors that don't prevent compilation are rather odd. Shouldn't these be warnings, or at least the compiler should make it clear that they haven't prevented code emission?

I have a large, existing Angular 1 application, organised into a few hundred ES6 modules. Eventually I want to migrate it Angular 2, and thus probably TypeScript, but this is going to have to be a gradual process. Having the compiler throw hundreds of errors because my code lacks types isn't going to make this much fun.

All 92 comments

if you can use absolute path you can do this today by doing something like:

// Define a module

declare module "template.html!text" {
    var html: number;
    export default x;
}

then your code would look like

import Html from "template.html!text";  // Html is a number

It would be nice to not have to create manual declarations for every javascript module I want to import. I would think this keeps to the spirit of "Typescript is a superset of Javascript".

For example, I have an ES6 foo.js file sitting next to my bar.ts file. I'd love to just be able to:

import * as foo from 'foo.js'

and then have foo be an implicit any.

The problem is not the import, the problem is the type of your import (the type of foo); with no information about the shape of the imported module the compiler has no way of helping you. we have talked about something like:

import * as foo: IFoo from "foo";

Which would tell the compiler that you know shape of the module, and optionally you can pass any to just load the module with no checking.

I actually tried something like that just as guess when I was playing around with it :)

The issue I think I'd still have is that I couldn't just take a bunch of es6 javascript files and one by one convert them to typescript without breaking everything. I love the fact that I used to be able to take a .js file, change the suffix to .ts, run it through the compiler and it would work.

I wonder if there could be a compiler flag like the impilictyAny option, something like allowImplicitAnyImports that would tell the compiler to only pull type information from the import if it is available. If you want to be strict about imports and/or use the explicit typing syntax you described, you could turn it to false.

Using TypeScript 1.5-beta, transpiling to ES6.

import { Foo } from 'foo';
export class Bar {
    constructor() {
        new Foo();
    }
}

The above code complains:

Cannot find external module 'foo'.

However, the following JavaScript is generated:

import { Foo } from 'foo';
export class Bar {
    constructor() {
        new Foo();
    }
}

As far as static type checking goes, Foo is considered to be "any" so you can also call it as a function, use it in arithmatic, etc.

Interestingly, when building with gulp-typescript I don't get the error but atom-typescript does give me the error. I'm guessing there is a compiler option that controls this, but I am not sure what it is (which is why I am here).

@Zoltu please see my comment in https://github.com/Microsoft/TypeScript/issues/3019#issuecomment-98821868 to answer your question..

However, the following JavaScript is generated:

TypeScript errors do not block emit. it tells you the compiler did not understand some aspects of your code, but syntactic transformations still take place.

As far as static type checking goes, Foo is considered to be "any" so you can also call it as a function, use it in arithmatic, etc.

You need to tell the compiler the shape of the thing you are importing. currently the only way to do that is to write a .d.ts file e.g.:

declare module "foo" {
    export class Foo{ }
}

I'm coming to this as a newcomer, having only recently started playing with TypeScript as part of the Angular 2 developer preview. I presume there's going to be plenty more people who follow a similar path, so let me capture my impressions:

I appreciate the value of typing, but it's not my primary motivation for using TypeScript. I'm more interested in decorators and the fact that its the recommended language for Angular 2. My expectation was that typing would be an optional addition that I could gradually apply, but not that I'd have to immediately find or create type definitions for all my code and its dependencies.

Whatever the reason, throwing errors on valid JavaScript code is confusing when TypeScript is explicitly described as a superset of JavaScript. The first thing many people will do is load up an existing app and try to compile it. Getting a bunch of errors in response doesn't give a great first impression.

That "Cannot find external module" error is really bad. At first I thought it meant the compiler couldn't find the file on disk, so I spent quite a while moving it around and trying to figure out what was wrong. I also thought that it meant the compiler hadn't output anything. Compiler errors that don't prevent compilation are rather odd. Shouldn't these be warnings, or at least the compiler should make it clear that they haven't prevented code emission?

I have a large, existing Angular 1 application, organised into a few hundred ES6 modules. Eventually I want to migrate it Angular 2, and thus probably TypeScript, but this is going to have to be a gradual process. Having the compiler throw hundreds of errors because my code lacks types isn't going to make this much fun.

@jonrimmer This is good feedback. Would be curious to here what your preferred workflow would've been.

As far as the module errors go, I totally agree they're pretty bad and very painful to debug.

As for the superset/errors part, what behavior would you prefer? Keep in mind the errors you're seeing are more like warnings in most languages, they can be ignored and JS is still emitted (were you using VS or some other editor?). Then you can fix up those errors over time. Some of them are to satisfy the compiler, some might be actual bugs in your code. The hope is that you can grab an existing .d.ts from DefinitelyTyped for much of your library code and fix any errors related to common code. We also have some ideas for ways to ease this process further (ex #2916).

If we didn't give those errors (ex some compiler flag like --noTypeErrors) then what would really be the point in starting to write with TypeScript? It'd be identical to your JavaScript except with an additional compile step in your workflow. Eventually you'd have to turn off the --noTypeErrors flag and be back in this state with many errors due to lack of type information. If you only got errors on the code you explicitly annotated then you'd actually have to write way more type annotations than necessary to get the type checking we advertise as powerful and useful.

@danquirk I am using Visual Studio Code. I can live with the current behaviour, but I wish the compiler's messaging was clearer. Something like "Warning: No registered type information for external module foo — using implicit 'any' type." If you have to keep calling them errors, some message making it clear that code is still being emitted would be helpful. @mhegazy's suggestion of being able to add an explicit type, even if it's any, to the import to shut up the compiler would be nice as well.

As for using TypeScript with untyped code, I actually get a lot. First, I get all the other ES6 and ES7 features you guys have implemented. In particular, I get to use Angular 2's annotations, which require decorator support. If you compare the TS vs ES5 examples in the Angular 2 documentation you can see that the ES5 equivalent code isn't nice, whereas the TS version is pretty awesome. That alone would be enough to make me use TS for my Angular 2 code, regardless of typing.

Also, even if my existing codebase and some of its dependencies aren't typed, by using TS for compilation, I can write all my new code with types, and gradually add them to the old code. I can also consume the core Angular 2 libraries in their original TS form, and get intellisense and checking on my use of them, at least.

Finally, I think maybe there's a question of project philosophy to consider here. It seems like until recently TypeScript existed in a niche where it existed to provide JavaScript + Types to people who wanted them, and could afford to be somewhat uncompromising in how it applied that vision. But its recent enhancements have turned it into more of a general ES.next compiler along the lines of Babel, and maybe that requires a reconsideration of how hard it pushes typing, vs. making interop with untyped code as painless as possible. I'm optimistic that types will make it into JS proper eventually. But with the best will in the world, there is going to be more untyped JS code around than not for a long time to come.

But what do you expect to happen with your untyped code? Do you want some way to turn off all type checking for a file? I get that the migration initially involves a lot of type errors but what do you envision instead? Even with file level settings as soon as you want to add type annotations to one function in that file you need to deal with the many errors from that file.

The entire purpose of emitting in the face of these type errors is to acknowledge how much untyped code is out there. Then the migration process to TypeScript can happen piecemeal without having broken your entire application until you've dealt with every single type error.

TypeScript is definitely aiming to add value in the form of ES6/7/etc features before they're in every browser/engine. But the fundamental point of the project is types (hence the name :)). There have always been type-less transpilers and will continue to be. What parts of the migration process are particularly painful to you with the .d.ts on DefinitelyTyped and if #2916 existed to easily get .d.ts for your JSDoc'd code? (I assume a bunch of code without JSDocs would be one).

I seem to recall at one of Anders talks at Build 2015, he _again_ referenced how any valid javascript file was a valid typescript file. I'd vote for, again, having a compiler switch similar to allowing implicit anys. If typescript can find a type for a module import, use it, else use "any". If people want to be strict, they can set it appropriately. For cases where you are starting new with Typescript, you can set the flag to strict, and then for external, untyped modules, use some sort of language construct (see @mhegazy idea above) to explicitly set the import type to "any". For existing code bases, you can set the compiler to allow implicit any imports.

I really love Typescript, it's a wonderful, powerful tool. I think it's adoption has been so high in part because it's so flexible (both in the optional typing and it's cross platform behavior). It plays nice with the existing Javascript ecosystem. The current module implementation unfortunately does not.

Is Mohamed's suggestion of

import * as foo: IFoo from "foo";

enough to satisfy all the use cases here? Basically the logic would be that if we see a type annotation (: IFoo in this example) on the target of an import, we would "skip" resolution of the "foo" module and trust that you knew what you were doing.

It would work for my current cases, where I'm starting with a Typescript code base and want to import a js library without any type defs. Partial conversion of an es6 .js project to .ts still seems more painful than it needs to be (going through and adding : any annotations to all your imports), but that may just be a very slim use case.

Howdy,

Dealing with a large existing untyped codebase and porting it to TypeScript is something that does and will happen frequently, I agree with the sentiments @dfaivre in this respect - there should be an 'implicitly any' flag for the compiler.

The idea of typing import * as foo: any from "foo" may bring issues when you properly convert "foo" into typescript - now you "want" to make sure everything adheres to the module type definition, but the compiler will ignore it unless you go back through your code again(!) and remove the typing from the import.

I think typescript should make the transition easy and make saying "now I care about the types of this module" simple - so I don't have to edit existing typescript code to make it all care - I can do it through one (or two) actions:

  1. Provide a typing file / port a module to typescript (partial modules should throw errors if there's missing members/methods in use) - i.e. now I care about the types in this module,
  2. Tell the compiler that I now want to treat all missing module typings as errors - i.e. now I care about the types in every module.

To achieve this I think these things need to happen:

  1. reduce the ERROR to a WARN, errors are scary, maybe it should be scary if a project is typescript and has been for a while, otherwise it's just confusing and off-putting,
  2. to prevent cascading warnings and to allow the default 'I don't care about types here', type any unresolved module type to 'any',
  3. Add a compiler flag to treat module type resolution warnings as errors.

Two sides to the same story of course - but I think you can cater for both camps:

  1. New developers - to increase adoption and make the transition simpler, the defaults should be easy to understand and not scare developers away but guide them to leverage typing,
  2. Existing developers - want all the potential warnings to flag up, but they are existing developers and know the TypeScript compiler more intimately so will have no trouble activating a flag to treat the warnings as errors.

In terms of what to do when partially migrating source to TypeScript, those partially typed modules may now throw errors - but that's a good thing - by partially typing you're indicating that you do now care about the type of the module.

This is good feedback on migration pain. I would just note that of your 3 suggestions there 2 are actually in place, just somewhat poorly communicated. Our errors are actually more like warnings in the sense that they will not block a build/emit phase. So while your migrated JavaScript may have errors reported by the TypeScript compiler (including module type resolution ones) you should still be getting emit that makes sense for the most part (syntax errors are another story).

+1 for import * as foo: IFoo from "foo"; and variations

That would support importing html strings and json objects,

e.g.
import myTemplate: string from "./my-template.html"
import myConfig: IConfig from "my-config.json"

One serious issue with treating untyped modules as errors is that it can fail the build process in Visual Studio and MSBuild in general. I have had to explicitly disable the "No emit on error" checkbox for a lot of projects; I feel it would be much better if untyped modules were raher shown as warnings.

It also fails browserify, e.g. this code in index.ts:

import * as $ from 'jquery';

$(() => {
    alert('hello world');
});

when compiled with this command:

browserify index.ts -p tsify --outfile bundle.js

will fail with the error:

TypeScript error: index.ts(1,20): Error TS2307: Cannot find module 'jquery'.

On another note, if it was possible to explicitly ignore specific TS** errors, that would be an acceptable workaround, e.g. something like this in tsconfig.json:

{
  ignoreRules: {
    "TS2307": true
  }
}

Just want to echo the sentiment that an error message is scary. If it's non-fatal, feels like it should be a warning instead. As a newcomer considering TypeScript, this sends a strong message that the road ahead will be rocky.

:+1:

:+1: for import myTemplate: string from "./my-template.html"

I've been using TypeScript since it was first announced, and I absolutely love it. I've been using TypeScript with systemjs for a few days now, and I find it an extremely fun and productive workflow. I get all of the intellisense and errors from my IDE, while completely bypassing need for a file system build step. It really makes TypeScript feel like a first class language in the browser. Unfortunately the inability to specify HTML imports for my angular templates without getting tooling errors is quite frustrating. Everything works but I dislike tolerating any errors as they drown out other errors. I understand there is a workaround that involves declaring modules with dummy exports and using absolute paths but this feels very clumsy. I would love a way to inform the compiler that certain files should be treated as resources, perhaps via a type annotation, without losing the current advantages of strong type checking for modules.

:+1: import template: string from "./templates/sidebar" :pray:

+1 also would like to see this.
For now I have solved it with generating ts/js files from the templates. I am referencing: "./my-template.html" and I am creating files like: my-template.html.ts and my-template.html.js (with content exported)
With this ts compiler is happy and jspm is happy also.

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:pray: import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:heavy_plus_sign: :dolphin:

:+1: !

:+1:

https://medium.com/@bestander_nz/fighting-typescript-for-webpack-c5127b55ec86

:+1: Would love to see something along the lines of import myTemplate: string from "./my-template.html" being implemented.

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1:

:+1: for import myTemplate: string from "./my-template.html"

Seems like a clean syntax and would help me immensely right now.

:+1: for import myTemplate: string from "./my-template.html"

:+1: for import myTemplate: string from "./my-template.html"

:+1:

:+1: for import myTemplate: string from "./my-template.html"

My 2 cents: This seems rather ridiculous that I can't use external modules that don't having typings. I understand the value of typings but i'm not going to go and write typings for every module I use. It will end up users not using modules they want to use because there aren't TSDs for them. Also, if I were converting a project this would be a NIGHTMARE!

Warnings instead of Errors make sense, because although errors makes you take action, they can also scare people away or waste precious time like @jonrimmer did, which I think did a very good job summarizing how Angular 2 developers approach it.

Anyone from the typescript team can let us know if there are any plans for one of the following:

  • warnings instead of errors?
  • :any for specific use case
  • a compiler flag

?

Thanks!

warnings instead of errors

What is the difference between a TypeScript warning instead of an error? Neither blocks emit unless you use --noEmitOnError anyway.

: any for a specific use case
a compiler flag

Sorry, do you specifically mean with respect to this issue? If so, this is an issue we've been thinking about and have run into ourselves as well. We're not 100% sure what the solution will be at this point.

About the difference, I think @masonicboom summarized it well:

Just want to echo the sentiment that an error message is scary. If it's non-fatal, feels like it should be a warning instead. As a newcomer considering TypeScript, this sends a strong message that the road ahead will be rocky.

Plus also having errors that don't break the compilation might not be that intuitive, plus plus - if you start to ignore them you might have a hard time finding other true errors. (if you're dealing with an enterprise software migration with lots of libs without d.ts files)

Does it make sense?

Yes, that makes sense. We used to have a distinction between syntactic and semantic errors. Syntactic errors would block emit, while semantic errors would not. While it was often a blurry line, I think that was somewhat helpful for newcomers.

@amcdnl how is that any different from .d.ts files? That's almost exactly what you'd do in TypeScript, and it doesn't address this issue itself.

From my point of view, a warning is just as problematic.

I view

import myTemplate: string from './my-template.html';

as a _Type Assertion_ in the module space. Valid type assertions do not issue errors or warnings and that is the point. What I think would be valuable would be for the compiler to validate the existence of the file and to allow for an assertion which would ascribe to it an export of the desired type. Since there is no reasonable fallback type, e.g. any, for the compiler to infer it makes sense that the type must be specified explicitly. I do not care what the syntax ultimately is.

@amcdnl this has nothing to do with the presence or absence of declarations at all. This is about importing things which are _actually not_ modules at all. An HTML template is not an external module file lacking a TypeScript declaration file, it is something which is supplied by a loader, and this request is about having a way to reference that entity, whatever it is, in TypeScript code such that an aware loader, can supply it dynamically.

The workaround that many people including myself are using is to generate a spurious declaration file containing dummy module declarations having unused arbitrary default exports. However this is actually somewhat misleading as it is just a way to fool the compiler. What is desired is a way to inform the compiler that something actually exists and will be resolved to an object of the given type by some other component in the tool chain. Typically, this is a loader, but it could be a bundler or anything really.

This is not an issue with declaration files as their _purpose_ is to describe the shape of the interface of an actual code artifact, hence the analogy with C header files. In the case of HTML templates and other resources, there is nothing to which the declaration maps.

@aluanhaddad i see. i dint understand why it cares, if it has types use that otherwise ignore it.. i import templates and css via systemjs import statements so that wouldnt even work for me. see this example https://github.com/Swimlane/angular-systemjs-seed/blob/master/src/app/login/login.js#L11

:-1: for generating a warning instead of an error.

I understand the frustration of people trying to migrate existing JS codebases.
But migration is a one-time thing.

On the other hand, there are people working on large code bases where everything should be typed (noImplicitAny etc.) and having an unknown import is most certainly a typo that needs fixing.
It is as much an error as for example using an undeclared variable (typo?).

If this behavior is really wanted, I would like to see it behind a compiler flag, like allowAnyImport.

I also have the impression that a lot of people in this thread want to import data: html templates, css styles... This is a common thing to do with various web frameworks, would it be worthy of support in TS? Like defining systemjs or requirejs plugins: loader: { "!text": "string" } and then TS types automatically all of those?

@jods4 I don't think that's necessary as the result would always be a string. Furthermore, a common scenario is using a path without a plugin specifier, e.g../myTemplate.html instead of ./myTemplate.html!text (SystemJS) or text!./myTemplate.html (RequireJS).

@aluanhaddad could match on .html instead of !text then? (this should be a config of course, not saying it's hard-coded into the compiler).

@aluanhaddad #5787 being addressed would deal with your use cases.

Is there already some proposal being accepted/developed?

closing in favor of #6615.

https://github.com/systemjs/plugin-text

import template from 'app/index/index.template.html!text';

Works for me.

Newcomer to Typescript here. Read the whole issue but it's not clear to me yet how importing untyped javascript modules is going to be in 2.0?

I find very frustrating that I can't just import * as packageAlias from "npm-package" if I don't have the typings for the package. The compiler error doesn't help either when it says it couldn't find the module.

I'd really like to write that line and if TypeScript cannot find definitions for "npm-package" then packageAlias should be simply of type any. Only then TypeScript could be called a superset of Javascript.

@emzero

Try something like this
_unknown.d.ts_

declare module "npm-package" { var e; export = e; }

In 2.0 there will be an even shorter declaration form.

@aluanhaddad

So I have to declare a module for every untyped npm packaged I want to use? There's no way of importing it directly as any?

If you enable allowJs it may work, but it will depend on the shape of the module you're importing. The salsa project aims to allow this for a certain set of module formats, I haven't messed around with it much. A lot of these features are available in the nightly builds.

if you are using typescript@next you can use short-hand module declarations combined with wildcard module names to switch off module verification for certain groups of modules e.g.

declare module "npm-package\*";  // any module import with this prefix is considered `any`.

see https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#shorthand-ambient-module-declarations

@mhegazy That's better but you still have to declare module for every npm package you want to play with.

Why can't just TypeScript do import * as Package from "npm-package" and set Package type to any if it can't find a type declaration for it?

if you want to disable all module checking, use "declare module "*";. I should warn here that a lot of the value that the TS tooling provide relies on getting type information.

@mhegazy I don't want to disable all module type checking. I have npm packages that include their own d.ts file, I also use typings for other d.ts files and then, there are some packages for which d.ts files do not exist anywhere.
By the time I want to do some quick playing with a new library (that I might not end using after all), I'd just rather import it as any without declaring anything. Later, if I decide I'll be using the library, I might create a d.ts file if it doesn't exist yet.

But according to what I've been reading, this is not possible and it won't be possible either in 2.0. A declare module... line has to be there for a module without declarations.

if a declaration file is found the compiler uses it. if not, it issues an error for unknown module. if i understand correctly you do not want to see this error. declare module "*"; effectively shuts off this error. if the declaration file is there, it will always be loaded. not sure i see what else can be done here.

declare module "*"; should match only the modules that don't have explicit declarations, correct? So given the following code:

# declarations.d.ts
declare module '*';

# index.ts
import * as $ from 'jquery';
import * as _ from 'lodash';

If I have only installed typings for jquery, I would expect intellisense for $, while _ would be treated as any.

EDIT: Actually I can confirm that this is working just as intended, after setting typescript.tsdk in VSCode and installing typescript@next. I am getting full intellisense for jQuery, while lodash is treated as any. Awesome :+1:

@geirsagberg:
I created a declaration.d.ts in the typings folder, added declare module '*';
and added the following the index.d.ts:
/// <reference path="declarations.d.ts" />
But I still get a error when I try the following:

import template from './app.component';

What else is needed ? please

isn't

# declarations.d.ts
declare module '*';

dangerous as you won't get any real errors either on missing modules?

I am still having an issue with this (Sep 2016)

I am using systemjs with the text plugin and angular2, so I am importing templates as:
import RatesTableTemp from './RatesTable.html!text';

@Component({
    selector: 'RatesTable',
    moduleId: __moduleName,
    changeDetection: ChangeDetectionStrategy.OnPush,
    styles: [`
        .rateInput {
            width: 40px; 
            color: #0f0f0f;
        }
        .btn span.fa {                
            opacity: 0;                
        }
        .btn.active span.fa {                
            opacity: 1;                
        }
    `],
    template: RatesTableTemp
})

everything works great
but TS gives an annoying error
of

 Error:(10, 28) TS2307:Cannot find module './RatesTable.html!text'.

any way to quiet the error down?

any way to quiet the error down?

declare module '*!text' {
    var _: string;
    export default  _;
}

thanks sooooo much!
Sean.

Is there anything special I have to do to reference the .d.ts file so that my imports work? I can't seem to get the solutions listed here to work.

// webpack.d.ts
import {IUseableStyle} from './common/IUseableStyle';

declare module '*.html' {
    var _: string;
    export default  _;
}

declare module '*.scss' {
    var _:  IUseableStyle;
    export default  _;
}
// component.ts

import template from './component.html'; // [ts] cannot find module './component.html';

tsconfig.json looks like:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "noImplicitAny": true,
    "outDir": ".tmp/src/",
    "allowJs": true,
    "target": "es6",
    "allowUnreachableCode": true
  },
  "include": [
    "/src/**/*"
  ]
}

Your .d.ts is a module (i.e. it has a top level import or export), modules have their own scope. this makes all declaration in this file not visible outside it. your file should look like:

declare module '*.html' {
    var _: string;
    export default  _;
}

declare module '*.scss' {
    import {IUseableStyle} from './common/IUseableStyle';
    var _:  IUseableStyle;
    export default  _;
}

Wildcard is not working for me , maybe it's due to I use typescript 1.8.
This doesn't work:

declare module '*.html' {
    var _: string;
    export default  _;
}

The following works fine:

import "text!Components/Templates/MyTemplate.html";
...
var template = require('text!Components/Templates/MyTemplate.html');

@bomzj Wildcard only works in TS 2.0 or higher.

EDIT: never mind. It seems that the README for the svg-inline-loader plugin is wrong. You need to use 'svg-inline-loader' as the loader name.

// webpack.config.js
config.module.loaders.push({
  test: /\.svg$/,
  loader: 'svg-inline-loader'
});

I've tried to follow through this issue but I'm a bit lost and would appreciate some help.

I'm trying to load a SVG file into my .ts file, so I can use it in my HTML template (Angular 2) as an inline SVG. This allows me to change the colour of the SVG with CSS. I'm using web pack 1.x.

This is what I've tried:

// webpack.config.js
config.module.loaders.push({
  test: /\.svg$/,
  loader: 'svg-inline'. // Installed locally with `npm install svg-inline-loader`
});
// declarations.d.ts
declare function require(string): any;

declare module "*.svg" {
  const content: any;
  export default content;
}
// Tried both this:
import damSvg from '../../../assets/icon/barrier-types/dam.svg';

// And this:
const damSvg = require('../../../assets/icon/barrier-types/dam.svg');

In both cases, I get a webpack 'Cannot find module' error.

Can anybody shed any light on what I'm doing wrong?

You either have the wrong path or you haven't listed .svg as a resolvable extension.

resolve: ['.svg', '.ts']

Your question would probably be better asked on stack overflow. it also has nothing to do with TypeScript , being about Webpack loading neither TypeScript nor JavaScript files

@aluanhaddad thank you for taking the time to respond. It ended up being an error with the loader I was using. I've updated my post above.

I didn't realize your issue was resolved (but I'm glad to hear it). I guess I'm used to seeing edits in bold.

Is there a way to import a file, raw as is, as a string, using Typescript purely?

I dont want to involve SystemJS, webpack or rollup to solve this problem.

TypeScript does not provide run-time functionality. If emitted TypeScript runs under NodeJS this functionality is already there. There are other libraries that provide similar functionality in the browser.

@avindra
Did you get any solution for your problem. I am also trying to import markdown(.md) files in typescript without using webpack and other module.

I have written in typing.d.ts

declare module *!txt* { const value: any; export default value; }

in TS file

import * as readme from "./README.md!txt"; // I am getting error for this.

@kitsonk could you suggest library which can be used to import non-code module in typescript.

Nothing worked for me, until I've changed my import to the * as <x> format.

This works with TS 2.4.1:

declare module '*.pegjs' {
    var _: string;
    export default _;
}

Then:

import * as cypher from './grammar/cypher.pegjs'

And the relevant parts of webpack config:

var config = {

    resolve: {
        extensions: [ '.ts', '.js', '.pegjs' ],
    },

    module: {
        rules: [{
            test: /\.pegjs$/,
            use: 'raw-loader',
        }]
    },
}

module.exports = config;

I tried this:

declare module "mirage-server"

import MirageServer, { Factory } from 'mirage-server';

but get:

error TS2665: Invalid module name in augmentation. Module 'mirage-server' resolves to an untyped module at '/Users/nikos/WebstormProjects/client/node_modules/mirage-server/lib/index.js', which cannot be augmented.

@QuantumInformation You can't put the declare module line in the same file as the imports, it's got to go into a .d.ts file.

Was this page helpful?
0 / 5 - 0 ratings