-->

Typescript error runtime error: Cannot read proper

2020-02-26 14:29发布

问题:

So I'm getting the above error in the console. It's caused by _super being undefined when it's passed to __extends (in the generated .js).

Here's some test code that can be used to reproduce the error:

//This is the entirety of the file Test.ts
module Test {
    export class Test1 {
        public Name: string;
        public Number: number;

        constructor() {

        }
    }
}

Then in a separate file I have a class that inherits from that one:

/// <reference path="Test.ts" />
module Test {
    export class Test2 extends Test1 {
        constructor() {
            super();
        }
    }
}

The <reference path... shouldn't be needed (and isn't), but I added it to see if it helped (it didn't).

The files are included in the correct order (Test.ts then Test2.ts) via BundleConfig (running with or without optimisations doesn't have any effect).

I am probably being a giant noob, but I haven't the slightest clue what I've messed up. All the other instances of this problem I've found online are from folks using the command line compiler to combine multiple Typescript files into one single file. I'm using the bundler to do that, but even when I don't combine them, I get the exact same issue.

Please help me, I'm at my wits end!

As requested, here's the compiled javascript: Test.js:

//This is the entirety of the file Test.ts
var Test;
(function (Test) {
    var Test1 = (function () {
        function Test1() {
        }
        return Test1;
    })();
    Test.Test1 = Test1;
})(Test || (Test = {}));
//# sourceMappingURL=Test.js.map

Test2.js:

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
/// <reference path="Test.ts" />
var Test;
(function (Test) {
    var Test2 = (function (_super) {
        __extends(Test2, _super);
        function Test2() {
            _super.call(this);
        }
        return Test2;
    })(Test.Test1);
    Test.Test2 = Test2;
})(Test || (Test = {}));
//# sourceMappingURL=Test2.js.map

回答1:

Possible reasons this is happening:

  1. Quadruple-check that BundleConfig is concatenating the files in the correct order. This is by far the most common cause of that error.
  2. Verify you don't have any top-level export directives in Test.ts. This would cause the file to become an external module and Test1 would no longer be visible.

Failing that, you should post the emitted JavaScript to the question so we can diagnose what's causing the issue.



回答2:

Incurred in this error today. Not sure what was the OP scenario, but in my team's case we had:

  1. TypeScript v1.8.10
  2. Webpack-based development build with concatenation, source maps, no optimization/uglification
  3. Angular 2 dependency injection
  4. Both base and derived classes defined in same file (say, dependencies.ts)
  5. Base class defined after derived class
  6. No compile errors nor warnings
  7. Console log showing Uncaught TypeError: Cannot read property 'prototype' of undefined
  8. Call stack pointing at internal __extends function on the last line of another class, in another file (say client.ts), importing those as dependencies

In code:

// dependencies.ts

import { Injectable } from 'angular2/core';

@Injectable()
export class LocalStorageService extends BaseStorageService {
  constructor() {
    super(localStorage);
  }
}

class BaseStorageService {
  constructor(private storage: Storage) {}
  // ...
}

and:

// client.ts

import { Injectable } from 'angular2/core';
import { LocalStorageService } from './dependencies';

@Injectable()
export class AuthStorageService {

  constructor(private permanentStorage: LocalStorageService) { }
  // ...

} // <-- call stack pointed here with inner '__extends' function

Problem solved by defining base class before derived class. After a quick search & read, this seems related to known (and unresolved?) TypeScript issues, e.g. #21 and #1842.

HTH



回答3:

The order of the scripts on your HTML matters.

Say you have a TypeScript file A.ts that defines an abstract class and a file B.ts with a class that extends the abstract class in A.ts

export abstract class ShipmentsListScope implements IShipmentsListScope {

A.ts:

module app.example{
  "use strict";

  interface IMyInterface{
    // ..
  } 
  export abstract class MyAbstract implements IMyInterface{
    // ..
  }
}

B.ts

module app.example{
    "use strict";

  class MyChildClass extends MyAbstract {
    // ...
  }
}

then in your HTML you have to ensure that the order of the scripts is correct once the javascripts have been generated:

<script src="/app/example/A.js"></script> <!-- A.js BEFORE -->
<script src="/app/example/B.js"></script>


回答4:

I had the same problem and it was caused by export default statements. To fix it I simply removed those and imported the required items another way:

BEFORE

A.ts

export default MyClass;

class MyClass { ... }

B.ts

import MyClass from "./A";

class MyClass2 extends MyClass { ... }

AFTER

A.ts

export class MyClass { ... }

B.ts

import { MyClass } from "./A";

class MyClass2 extends MyClass { ... }


回答5:

Just leaving here how I solved this issue for my case : I missed a reference at the top of the TS file and it was totally ok for the build, whereas I had the same error on runtime. Adding the reference that seemed to be optional solved my runtime issue.