Skip to content

Compiler generates jsxFactory call with incorrect namespace #29376

Open

Description

@MaceWindu

TypeScript Version: 3.2.2, 3.3.0-dev.20190111

Search Terms:
jsx, jsxFactory

Code
Full solution: test.zip

namespace Templates {

    export function compile(_: string, __: { [key: string]: any }, ...___: Array<any>) {
        return {};
    }
}
// this template generated properly as call to Templates.compile
namespace SomeNS.Templates.OtherNS {
    export const Boolean = (props: {
        id: string;
        name: string;
    }) => {
        return (
            <input type="checkbox" id={props.id} name={props.name} />
        );
    }
}
// this template generated as call to non-existing SomeNS.Templates.compile
namespace SomeNS.templates {
    export const text = (value: string) => <span>{value}</span>;
}
{
    "compileOnSave": false,
    "files": [
        "root.ts"
    ],
    "compilerOptions": {
        "noEmitOnError": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "removeComments": true,
        "target": "es5",
        "strict": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "forceConsistentCasingInFileNames": true,
        "noErrorTruncation": true,
        "allowJs": true,
        "lib": [
            "dom",
            "es5"
        ],
        "stripInternal": true,
        "declaration": false,
        "jsx": "react",
        "jsxFactory": "Templates.compile"
    }
}

Expected behavior:
Proper call to jsxFactory method generated

Actual behavior:

Generated code contains call of non-existing method (SomeNS.Templates.compile instead of Templates.compile):

"use strict";
var Templates;
(function (Templates) {
    function compile(_, __) {
        var ___ = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            ___[_i - 2] = arguments[_i];
        }
        return {};
    }
    Templates.compile = compile;
})(Templates || (Templates = {}));
var SomeNS;
(function (SomeNS) {
    var templates;
    (function (templates) {
                // unknown SomeNS.Templates.compile method called
        templates.text = function (value) { return SomeNS.Templates.compile("span", null, value); };
    })(templates = SomeNS.templates || (SomeNS.templates = {}));
})(SomeNS || (SomeNS = {}));
var SomeNS;
(function (SomeNS) {
    var TestClass = (function () {
        function TestClass() {
        }
        TestClass.prototype.test = function () {
            return SomeNS.Templates.OtherNS.Boolean({
                id: 'id',
                name: 'name'
            });
        };
        return TestClass;
    }());
    SomeNS.TestClass = TestClass;
})(SomeNS || (SomeNS = {}));
var SomeNS;
(function (SomeNS) {
    var Templates;
    (function (Templates) {
        var OtherNS;
        (function (OtherNS) {
            OtherNS.Boolean = function (props) {
                // proper Templates.compile method called
                return (Templates.compile("input", { type: "checkbox", id: props.id, name: props.name }));
            };
        })(OtherNS = Templates.OtherNS || (Templates.OtherNS = {}));
    })(Templates = SomeNS.Templates || (SomeNS.Templates = {}));
})(SomeNS || (SomeNS = {}));

Activity

  1. ajafff commented on Jan 11, 2019

    @ajafff
    Contributor

    Since you are effectively shadowing the other Templates, there is no way to actually access it at that point. If you look closely you'll see it always calls the wrong/non-existent Templates.compile method.

    Also note that your transpiled code doesn't match the original source. Namespaces are in a different order and where's the class coming from?

    What could be done is detecting that the shadowing Templates doesn't have a compile method.

  2. added
    SuggestionAn idea for TypeScript
    Needs ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.
    on Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: Error MessagesThe issue relates to error messagingNeeds ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.SuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions