Search code examples
angulartypescriptbuildangular-ivy

Angular 9 Ivy build - extension errors


Good morning!

I've recently updated a v8 project to v9, and it seems to work fine. However, I have some extensions and the compiler throws up some errors about them, which it doesn't do in another project that I also recently upgraded.

The extensions are the basic kind, for both constructor and proto. They are set up fine - the same setup works in the multiple projects I have them in. Crucially, they work fine without any errors in the other upgraded project.

However, to get the basic usage confirmations for all out the way:

Adding iface to typings.d.ts, e.g.

interface StringConstructor {
  isNullOrEmpty(str: string): boolean;
}  
interface String {
  padStartWithChar(char: string, totalSize: number): string;
}

Implementation, e.g.

export {};

String.isNullOrEmpty = function(str: string): boolean {
  // ...
};

String.prototype.padStartWithChar = function(this: string, char: string, totalSize: number): string {
  // ...
}

And importing in main.ts

// ...
import './extensions/string-extensions';
// ...

My paths haven't changed, they all point to all the right files in all the right places that I can think to check for them (src/typings.d.ts is in src where I put it, tsconfig.app.ts includes it as it did before, etc. etc.).

Which leads to build errors; I get a spam of errors for all usages of the extensions and the build eventually halts:

...

src/extensions/string-extensions.ts:9:8 - error TS2339: Property 'isNullOrEmpty' does not exist on type 'StringConstructor'.

9 String.isNullOrEmpty = function(str: string): boolean {

...

** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

and attempting to browse results in the Cannot GET/ basic message. However, it does the usual re-build on saving of files wherein it shows all those error messages again, but completes the build anyway this time and works.

Does anyone have a direction to point me in that I may have missed? Between the two projects I've checked for any significant changes between angular.json, tsconfigs, main.ts, etc. but so far I'm coming up empty.

Thanks.

Edit:

Reverting and attempting the upgrade again, the extensions break at the very first step of the update guide just by running the slight update with ng update @angular/core@8 @angular/cli@8.

From that update onwards, it dies. Skipping that step (I'm already running a v8 app anyway) and trying to upgrade straight to 9, sadly also kills it.

Update:

Richard's answer seems to have gotten rid of all bar the Date extension error messages. It doesn't seem to like the existence of a DateConstructor interface at all, and it also doesn't seem particularly happy about usages of moment, when attempting his method.

Update edit:

Date extensions all look exactly like the other extensions, the singular difference is that there's an import moment from 'moment' line in there. Removing such things doesn't seem to make a difference; it's like Dates are a different beast to Strings or Arrays...


Solution

  • Another project has the error, and I seems I've narrowed it down!

    I had build warnings akin to Add only entry points to the 'files' or 'include' properties in your tsconfig.

    Having taken a look and comparing my tsconfig.app.json file in this newest project I'm updating vs the other, paired with the above warnings, it stood out!

    Previous config:

    {
      "extends": "../tsconfig.json",
      "compilerOptions": {
        "outDir": "../out-tsc/app",
        "baseUrl": "./",
        "module": "es2015",
        "types": []
      },
      "exclude": [
        "test.ts",
        "**/*.spec.ts"
      ]
    }
    

    New config, fixing the warnings (adding the files main and polyfills), and then also fixing the extensions:

    {
      "extends": "../tsconfig.json",
      "compilerOptions": {
        "outDir": "../out-tsc/app",
        "types": ["node"]
      },
      "files": [
        "main.ts",
        "polyfills.ts"
      ],
      "include": [
        "**/*.d.ts",
        "extensions/*.ts"
      ],
      "exclude": [
        "test.ts",
        "**/*.spec.ts"
      ]
    }
    

    Seems one needs to include such files!