0
votes

I've created an Angular2-component and want to share the code with my colleagues. I've uploaded the code to github, cloned the repo, did npm install and npm run tsc, but got:

error TS2318: Cannot find global type 'Promise'.
node_modules/@angular/common/src/directives/ng_class.d.ts(48,34): error TS2304: Cannot find name 'Set'.
node_modules/@angular/common/src/pipes/async_pipe.d.ts(44,38): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/application_init.d.ts(16,18): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/application_ref.d.ts(116,76): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/application_ref.d.ts(132,110): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/application_ref.d.ts(158,67): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/application_ref.d.ts(160,101): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/change_detection/differs/default_keyvalue_differ.d.ts(24,15): error TS2304: Cannot find name 'Map'.
node_modules/@angular/core/src/change_detection/differs/default_keyvalue_differ.d.ts(28,16): error TS2304: Cannot find name 'Map'.
node_modules/@angular/core/src/di/reflective_provider.d.ts(87,123): error TS2304: Cannot find name 'Map'.
node_modules/@angular/core/src/di/reflective_provider.d.ts(87,165): error TS2304: Cannot find name 'Map'.
node_modules/@angular/core/src/facade/lang.d.ts(12,17): error TS2304: Cannot find name 'Map'.
node_modules/@angular/core/src/facade/lang.d.ts(13,17): error TS2304: Cannot find name 'Set'.
node_modules/@angular/core/src/linker/compiler.d.ts(53,49): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/linker/compiler.d.ts(61,65): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/linker/ng_module_factory_loader.d.ts(14,34): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/linker/system_js_ng_module_factory_loader.d.ts(28,25): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/src/util/lang.d.ts(12,53): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/testing/component_fixture.d.ts(73,19): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/testing/test_bed.d.ts(85,33): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/core/testing/test_bed.d.ts(134,26): error TS2304: Cannot find name 'Promise'.
node_modules/@angular/http/src/headers.d.ts(52,59): error TS2304: Cannot find name 'Map'.
node_modules/@angular/http/src/url_search_params.d.ts(46,16): error TS2304: Cannot find name 'Map'.
node_modules/rxjs/Observable.d.ts(69,60): error TS2304: Cannot find name 'Promise'.
node_modules/rxjs/Observable.d.ts(69,70): error TS2304: Cannot find name 'Promise'.
node_modules/rxjs/observable/PromiseObservable.d.ts(40,31): error TS2304: Cannot find name 'Promise'.
node_modules/rxjs/observable/PromiseObservable.d.ts(41,26): error TS2304: Cannot find name 'Promise'.
node_modules/rxjs/operator/toPromise.d.ts(2,60): error TS2304: Cannot find name 'Promise'.
node_modules/rxjs/operator/toPromise.d.ts(3,79): error TS2304: Cannot find name 'Promise'.
node_modules/rxjs/operator/toPromise.d.ts(3,89): error TS2304: Cannot find name 'Promise'.
src/my.component.spec.ts(40,13): error TS2697: An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.
src/my.service.ts(59,28): error TS2339: Property 'find' does not exist on type 'Cmp[]'.
src/my.service.ts(59,34): error TS7006: Parameter 't' implicitly has an 'any' type.
src/my.service.ts(71,43): error TS2339: Property 'find' does not exist on type 'PartCmp[]'.
src/my.service.ts(71,49): error TS7006: Parameter 'pt' implicitly has an 'any' type.
src/other.service.spec.ts(122,3): error TS2304: Cannot find name 'expect'.
src/other.service.spec.ts(27,1): error TS2304: Cannot find name 'describe'.
src/other.service.spec.ts(28,2): error TS2304: Cannot find name 'beforeEach'.
src/other.service.spec.ts(35,2): error TS2304: Cannot find name 'it'.

This is my npm setup:

"dependencies": {
    "@angular/common": "~2.4.0",
    "@angular/compiler": "~2.4.0",
    "@angular/core": "~2.4.0",
    "@angular/forms": "~2.4.0",
    "@angular/http": "^2.0.0",
    "@angular/platform-browser": "~2.4.0",
    "@angular/platform-browser-dynamic": "~2.4.0",
    "@angular/router": "~3.4.0",
    "angular-in-memory-web-api": "~0.2.2",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.8",
    "rxjs": "^5.0.0-beta.12",
    "systemjs": "0.19.40",
    "zone.js": "^0.7.4"
},
"devDependencies": {
    "jasmine": "^2.5.3",
    "karma": "1.2.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-coverage": "^1.1.1",
    "karma-html-reporter": "^0.2.7",
    "karma-jasmine": "^1.0.2",
    "lite-server": "^2.2.2",
    "systemjs": "^0.19.37",
    "typescript": "2.1.5"
}

and my tsc-compiler setup

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": true
    }, "exclude": ["node_modules"]
}

I've already tried deleting node_modules/, typings/, changing the dependencies to the current dependencies from the angular starter, but I just got more error-messages.

Can anyone help me? My ultimate goal is for someone to get clone my repository, run npm install and npm run tsc, and be ready to develop.

Update1: Turning es5 to es6 removed the errors regarding the promises; the jasmine-errors are still there:

src/other.service.spec.ts(122,3): error TS2304: Cannot find name 'expect'.
src/other.service.spec.ts(27,1): error TS2304: Cannot find name 'describe'.
src/other.service.spec.ts(28,2): error TS2304: Cannot find name 'beforeEach'.
src/other.service.spec.ts(35,2): error TS2304: Cannot find name 'it'.

Update2:

I've updated the dependencies to match the angular-quickstart (https://github.com/angular/quickstart/blob/master/package.json). Now it works, thanks for the help!

1
Try changing target to es6. Promises are an es6 feature.schu34
node -v npm -v and paste it here. Are you using cli?kind user
node -v: v6.9.5Jonas Möller
Thanks, the es5 to es6 did changes to the promise-errors; I've updated the questionJonas Möller
Yap, you need to install types as npm packages (in this case, @types/jasmine). For future reference, use microsoft.github.io/TypeSearch to see which external modules needs to have the @types library installedrpadovani

1 Answers

1
votes

You are missing declarations for Promise and some Array methods in your tsconfig.json. Note the addition of the "lib" property below.

{
  "compilerOptions": {
    "lib": [
      "es2017",
      "dom"
    ],
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true
  }, 
  "exclude": ["node_modules"]
}

Furthermore, as noted by @rpadovani you are missing some @types packages for test frameworks.

While some in comments suggested that you change from "target": "es5", to "target": "es2015", this is a choice you must make very carefully as it restricts the set of browsers that can target dramatically unless you intend to introduce a secondary transpiler.

In this case there is likely no need to update the "target" property as Array methods like find can be supplied by a polyfill, such as core-js, and Angular 2 itself polyfills a global Promise by way of depending on zone.js. So do not be overly hasty to update "target", and instead consider configuring the "lib" option to obtain the type information that targets the newer runtimes/polyfills.

It is worth noting that updating the "target" option is a way to implicitly update the "lib" option which is why it was suggested. However, updating "target" also changes the degree of syntactic downleveling that is performed by TypeScript when it transpiles you code.

Consider

source TypeScript

class A {
    http = new Http();
    async retrieve() {
        const data = await this.http
            .get('api/settings')
            .map(r => r.json() as Settings)
            .toPromise();
        const withId = { ...data, id: 1 };
    }
}

emitted JavaScript "target": "es5"

"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
    return { next: verb(0), "throw": verb(1), "return": verb(2) };
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [0, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var A = (function () {
    function A() {
        this.http = new Http();
    }
    A.prototype.retrieve = function () {
        return __awaiter(this, void 0, void 0, function () {
            var data, withId;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.http
                            .get('api/settings')
                            .map(function (r) { return r.json(); })
                            .toPromise()];
                    case 1:
                        data = _a.sent();
                        withId = __assign({}, data, { id: 1 });
                        return [2 /*return*/];
                }
            });
        });
    };
    return A;
}());

emitted JavaScript "target": "es2015"

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class A {
    constructor() {
        this.http = new Http();
    }
    retrieve() {
        return __awaiter(this, void 0, void 0, function* () {
            const data = yield this.http
                .get('api/settings')
                .map(r => r.json())
                .toPromise();
            const withId = Object.assign({}, data, { id: 1 });
        });
    }
}

emitted JavaScript "target": "es2017"

"use strict";
class A {
    constructor() {
        this.http = new Http();
    }
    async retrieve() {
        const data = await this.http
            .get('api/settings')
            .map(r => r.json())
            .toPromise();
        const withId = Object.assign({}, data, { id: 1 });
    }
}

emitted JavaScript "target": "esnext"

"use strict";
class A {
    constructor() {
        this.http = new Http();
    }
    async retrieve() {
        const data = await this.http
            .get('api/settings')
            .map(r => r.json())
            .toPromise();
        const withId = { ...data, id: 1 };
    }
}