Skip to content

Cannot read property 'flags' of undefined TypeError when running tsc using 3.7.0-beta #34481

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

Closed
PissedCapslock opened this issue Oct 15, 2019 · 10 comments · Fixed by #34577
Closed
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@PissedCapslock
Copy link

PissedCapslock commented Oct 15, 2019

TypeScript Version: 3.7.0-dev.20191015

Search Terms:
getFlowTypeOfReference
Code

Project structure:

<project_root>
  |_ package.json
  |_ node_modules
  |_ tsconfig.json
  |_ src
      |_ Graphic.js

where package.json is

{
  "name": "tsc-error",
  "description": "sample project to reproduce an error using tsc",
  "version": "0.1",
  "devDependencies": {
    "typescript": "^3.7.0-dev.20191015"
  }
}

and tsconfig.json is

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "declaration": true,
    "allowJs": true
  },
  "lib": [
    "es5","es2015", "es6", "dom"
  ],
  "include": ["src"],
  "exclude": [ "node_modules" ]
}

and Graphic.js a JS file which still uses AMD modules

define([
], function() {

  var NULL_WRITABLE_HIDDEN = Object.freeze({
  });

  function Graphic() {
    Object.defineProperty(this, "_onlineResource", NULL_WRITABLE_HIDDEN);
    Object.defineProperty(this, "_inlineContent", NULL_WRITABLE_HIDDEN);
  }

  Graphic.prototype = Object.create(Object.prototype);
  Graphic.prototype.constructor = Graphic;

  Object.defineProperty(Graphic.prototype, "inlineContent", {
    get: function() {
      return this._inlineContent;
    },
    set: function(ic) {
      this._inlineContent = ic;
      this._onlineResource = null;
    }
  });

  return Graphic;
});

Running the tsc command produces an error.

Expected behavior:
The Typescript compiler can finish compilation without crashing

Actual behavior:
Typescript compiler threw an error

/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:78447
                throw e;
                ^

TypeError: Cannot read property 'flags' of undefined
    at getFlowTypeOfReference (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:41966:80)
    at tryGetThisTypeAt (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:43110:32)
    at checkThisExpression (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:43081:24)
    at checkExpressionWorker (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:48519:28)
    at checkExpression (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:48473:38)
    at checkOptionalExpression (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:40156:24)
    at checkPropertyAccessExpressionOrQualifiedName (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:44878:22)
    at checkPropertyAccessExpression (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:44866:20)
    at checkExpressionWorker (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:48546:28)
    at checkExpression (/tmp/tsc-problem/node_modules/typescript/lib/tsc.js:48473:38)

Playground Link:

Related Issues:

@Jack-Works
Copy link
Contributor

Also having this problem when try to generate dts for package matrix-js-sdk with the tsconfig:

Version 3.7.0-dev.20191017

{
  "compilerOptions": {
    "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
    "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
    "allowJs": true /* Allow javascript files to be compiled. */,
    "declaration": true /* Generates corresponding '.d.ts' file. */,
    "declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */,
    "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
  }
}

@Jack-Works
Copy link
Contributor

it's working on Version 3.7.0-dev.20190816 but not working on Version 3.7.0-dev.20190820

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Oct 17, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.7.1 milestone Oct 17, 2019
@andrewbranch
Copy link
Member

I’m not able to repro @PissedCapslock’s example at all. @Jack-Works’ example, interestingly, repros on 3.7.0-dev.20190820 as mentioned, works on 3.7.0-dev.20191017, but then crashes with the same error if you turn esModuleInterop back to false 🤔

@andrewbranch
Copy link
Member

Actually, @Jack-Works, the error I can reproduce in your repo is Cannot read property 'kind' of undefined with a fairly unrelated stack to what @PissedCapslock shared. What error message are you getting?

@Jack-Works
Copy link
Contributor

Actually, @Jack-Works, the error I can reproduce in your repo is Cannot read property 'kind' of undefined with a fairly unrelated stack to what @PissedCapslock shared. What error message are you getting?

I think get the same exception stack as the @PissedCapslock one

@PissedCapslock
Copy link
Author

@andrewbranch You are right. It cannot be reproduced with the code in the issue description. I slightly modified the code after posting the issue, and that resolved the bug.

If you remove the following lines again:

  Graphic.prototype = Object.create(Object.prototype);
  Graphic.prototype.constructor = Graphic;

you can reproduce the issue. Of course, one can argue that the JS is not correct at that point and that I should fix my JS first :-) .

To make it as easy as possible to reproduce, you can run the following commands:

git clone https://github.com/PissedCapslock/tsc-beta-compiler-bug.git
cd tsc-beta-compiler-bug/
npm install typescript@next
./node_modules/.bin/tsc

But not sure if this issue is still worth your time, seeing as I made an error in the Javascript. The only thing that would be nice is a better error message from tsc. For example, including the problematic file would already be helpful.

@andrewbranch
Copy link
Member

Indeed, I can reproduce it now. Thanks!

@andrewbranch
Copy link
Member

Minimal-ish repro:

function Graphic() {
}

Object.defineProperty(Graphic.prototype, "inlineContent", {
  get: function() {
    return this.x;
  }
});

And note a workaround is to tag Graphic with /** @constructor */

Of course, one can argue that the JS is not correct at that point and that I should fix my JS first... But not sure if this issue is still worth your time, seeing as I made an error in the Javascript. The only thing that would be nice is a better error message from tsc.

It’s true that your JS doesn’t check, but the reason we didn’t give you a proper error message is because we crashed during compilation. That’s never acceptable, regardless of how wrong your input is. We should be able to give you a good error message if you tried to compile the contents of A Tale of Two Cities, so we should certainly be able to handle almost-correct JavaScript.

@PissedCapslock
Copy link
Author

Thanks Andrew. Very nice to see how fast this bug went from being reported to being fixed.

@mlodato517
Copy link

mlodato517 commented Jan 8, 2020

Quick question on this because I feel like I may be seeing something similar.
Was the fix in #34577 to use exactly Object.defineProperty(Foo.prototype, ... as an indicator that Foo is a class?

Basically, I'm running into an issue from a custom downloaded portion of Highcharts. I think what's happening is the code has:

// ...
        function extend(a, b) {
            /* eslint-enable valid-jsdoc */
            var n;
            if (!a) {
                a = {};
            }
            for (n in b) { // eslint-disable-line guard-for-in
                a[n] = b[n];
            }
            return a;
        }
// ...
        var Chart = H.Chart = function () {
            this.getArgs.apply(this, arguments);
        };
// ...
        extend(Chart.prototype, /** @lends Highcharts.Chart.prototype */ {
            // Hook for adding callbacks in modules
            callbacks: [],
// ...

And I'm getting

TypeError: Cannot read property 'flags' of undefined
Occurred while linting highcharts-custom.src.js:17295 // that's the `this.getArgs` line
    at getFlowTypeOfReference (node_modules/typescript/lib/typescript.js:50419:80)
    at tryGetThisTypeAt (node_modules/typescript/lib/typescript.js:51810:28)
    at checkThisExpression (node_modules/typescript/lib/typescript.js:51767:24)
    ...

Am I running into the same error as above but because Highcharts uses a hand-rolled extend instead of Object.defineProperty, typescript isn't picking up the class-ness? If so, where can I throw that /** @constructor */ to workaround this? I tried:

        /** @constructor */
        var Chart = H.Chart = function () { /** @constructor */
            this.getArgs.apply(this, arguments);
        };

but neither of those worked.

Edit

Is it supposed to be @constructs?

        /** @constructs Chart*/
        var Chart = H.Chart = function () {
            this.getArgs.apply(this, arguments);
        };

Edit2

That seems to have fixed it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
5 participants