-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Importing defaults with es6 syntax doesn't work #5565
Comments
You need to write it as a namespace import (as opposed to a default import): import * as createLogger from "redux-logger"; |
Thanks @ahejlsberg , I understand that the defaults syntax works in my TS internal files but it doesn't work when I want import something from node_modules (external modules)? I have one more problem. When I do like you said ... applyMiddleware(createLogger()),` this gives me an error What I'm doing wrong? |
Oh, I see. Then you need to either do this: import * as reduxLogger from "redux-logger";
applyMiddleware(reduxLogger.createLogger()); Or this: import { createLogger } from "redux-logger";
applyMiddleware(createLogger()); I suspect the latter one is what you're looking for. |
@ahejlsberg In both cases I have undefined in my runtime. The only import which works is
but with this syntax I don't have typescript support. Redux-Logger library exports only one default function which is createLogger. Update 1: This one started working when I removed word "default" from function in my module definition
|
Are you using the SystemJS module loader? This looks like it might be the same problem as #5285 which has to do with SystemJS's "auto-magic" promotion of the default export. |
@ahejlsberg I'm using commonjs module loader. I compared my compiled code with babel code and here are two versions: Typescript:
Babel:
and in the runtime redux_logger_1 is a function and redux_logger_1.default is undefined. Babel code works because the condition inside function is true so it returns To sum up what I've said earlier: I discovered that Babel compiles default export to another syntax that Typescript and Typescript can't handle babel output. For example I have the following code:
In typescript
As I said the first output is incompatible with Typescript. The imports that don't work: With the second output I can just do |
Ok, I think I see what is going on. It appears the "redux-logger" module was transpiled with Babel. When Babel transpiles a module whose only export is an TypeScript doesn't do any of this magic (see here for more details). In order for TypeScript to consume the module you need to change the redux-logger.d.ts declaration file to actually reflect what is going on: /// <reference path="../redux/redux.d.ts" />
declare module 'redux-logger' {
function createLogger(options?: createLogger.ReduxLoggerOptions): Redux.Middleware;
namespace createLogger {
interface ReduxLoggerOptions {
actionTransformer?: (action: any) => any;
collapsed?: boolean;
duration?: boolean;
level?: string;
logger?: any;
predicate?: (getState: Function, action: any) => boolean;
timestamp?: boolean;
transformer?: (state:any) => any;
}
}
export = createLogger;
} Once you do that you should be able to import the module with a namespace import: import * as createLogger from "redux-logger"; or with the equivalent: import createLogger = require("redux-logger"); |
@ahejlsberg Thanks!! Works perfectly! |
@niba Good to hear. BTW, it appears that Babel is killing off the module.exports = exports["default"]; and continue to use the declaration file you already have. In that case your import should be: import createLogger from "redux-logger"; |
@ahejlsberg Good to know that. Thank you for the information! |
I know this was closed a while ago, I just wanted to pop in an give a HUGE THANK YOU to @ahejlsberg for that explanation and remedy You just made some things click for me with that. I literally wasted probably 4 hours trying to understand why my type definition, using I would offer that it's probably worth adding to the documentation here: As a special note for type definitions for Babel generated code. |
@aventurella Thanks. The complexities of ES6 module downlevel transpilation and interop is truly the gift that keeps on giving! |
Is this still a problem? |
It depends, for my money I have found that when I have an issue with a 3rd party lib I check to see if that lib was compiled with Babel. Usually it was so I just look at it's compiled source to see how it's exporting it and adjust my import accordingly |
@aventurella thanks for the quick response - can the problem be fixed by updating the typing file? |
The only way I have been able to "address" it is by understanding how the target 3rd party module has been exported. And you adjust things accordingly once you see how it's been exported by whatever transpiled it. Once you know that, if you are adding typings you just need to be sure you add them to describe the situation you observe in the 3rd party module. |
@aventurella - I really appreciate your detailed explanation - if you have a chance, could you give me a simple example please? |
What 3rd party module are you having an issue with? |
@aventurella - sorry for the late response, but here is the package that I use:
The definition file (types/quill v1.3.0) looks like this: code link - note that there is no default export in the definition file. And here is my code in *.ts file:
The compiled JS code is:
The problem here is that Now the definition file has been updated a few days ago, and it has the default export - but in v1.3.0, there is no default export. In this case, how can I fix the problem? Please advise...!! |
I encountered the same issue @niba was encountered with another library: cytoscape and it's type definition file. Actually I helped push the type definition to DefinitelyTyped, but I'm not so sure how to fix this after it's been merged. When I import the module: When I call with cytoscape type source on DefinitelyTyped: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d9ca7d7efff765abe162023a9aa47f51f473bfd7/types/cytoscape/index.d.ts |
@wy193777 the named export is the problem. +export = cytoscape;
+export as namespace cytoscape; - export function cytoscape(options?: cytoscape.CytoscapeOptions): cytoscape.Core;
+ function cytoscape(options?: cytoscape.CytoscapeOptions): cytoscape.Core;
- export function cytoscape(extensionName: string, foo: string, bar: any): cytoscape.Core;
+ function cytoscape(extensionName: string, foo: string, bar: any): cytoscape.Core; - export namespace cytoscape {
+ namespace cytoscape { based on the package's source code Then you would import it via either import cytoscape = require('cytoscape'); or import cytoscape from 'cytoscape'; // --allowSyntheticDefaultImports true or referencing the global when not using modules, depending on your environment. |
Thanks @aluanhaddad. I just submitted a new pull request to fix it. |
Syntax:
import name from "module-name";
doesnt work in my project with Typescript 1.6. The imported variable is undefined.Example:
import createLogger from "redux-logger"; //createLogger is undefined
This syntax works
import createLogger = require("redux-logger");
The text was updated successfully, but these errors were encountered: