Definitelytyped: @types/core-js breaks build in version 0.9.37

Created on 13 Mar 2017  ·  47Comments  ·  Source: DefinitelyTyped/DefinitelyTyped

  • [X] I tried using the @types/xxxx package and had problems.
  • [X] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [X] I have a question that is inappropriate for StackOverflow. (Please ask any appropriate questions there).
  • [X] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @rbuckton

It seems that there is some issues with the 0.9.37 core-js package and tsc 2.2.1

I get a lot of compiler errors: (just a clipout of them)
node_modules/@angular/core/src/facade/lang.d.ts(12,17): error TS2693: 'Map' only refers to a type, but is being used as a value here.
node_modules/@angular/core/src/facade/lang.d.ts(13,17): error TS2693: 'Set' only refers to a type, but is being used as a value here.
node_modules/@types/core-js/index.d.ts(47,36): error TS2304: Cannot find name 'Iterable'.
node_modules/@types/core-js/index.d.ts(350,48): error TS2304: Cannot find name 'PropertyKey'.
node_modules/@types/core-js/index.d.ts(351,52): error TS2304: Cannot find name 'PropertyKey'.
node_modules/@types/core-js/index.d.ts(352,34): error TS2304: Cannot find name 'PropertyKey'.
node_modules/@types/core-js/index.d.ts(353,34): error TS2304: Cannot find name 'PropertyKey'.
node_modules/@types/core-js/index.d.ts(354,34): error TS2304: Cannot find name 'PropertyKey'.
node_modules/@types/core-js/index.d.ts(355,61): error TS2304: Cannot find name 'PropertyKey'.
.....
node_modules/@types/core-js/index.d.ts(2103,41): error TS2339: Property 'toStringTag' does not exist on type 'SymbolConstructor'.
node_modules/@types/core-js/index.d.ts(2107,41): error TS2339: Property 'unscopables' does not exist on type 'SymbolConstructor'.
node_modules/rxjs/Observable.d.ts(69,60): error TS2693: 'Promise' only refers to a type, but is being used as a value here.
node_modules/rxjs/operator/toPromise.d.ts(3,79): error TS2693: 'Promise' only refers to a type, but is being used as a value here.
typescript\shared\login.component.ts(81,62): error TS2339: Property 'find' does not exist on type 'Unit[]'.
typescript\shared\login.component.ts(81,62): error TS2339: Property 'find' does not exist on type 'Unit[]'.

With the 0.9.35 everything works as expected.

I am wondering if it is the change in ts.config from es5 to ef2017 that causes this? Can't really see that any of the other changes could have done this?

Most helpful comment

By adding

"lib": ["es2017", "dom"]

to my compilerOptions in tsconfig.json solved this issue for me.

thanks @andy-ms

All 47 comments

We are also getting a lot of errors here. (Cannot find name "Promise", Cannot find name "Set", ...)
Reverting back to 0.9.36 solves the issue for us at this moment.

@andy-ms / @mhegazy

"Definitions by" says @rbuckton, but no response there. I see that the last commit are done by you. Any comments?

If it isn't @rbuckton that is responsible, maybe update index.d.ts with right responsible ?

Try setting --lib in your tsconfig to get the definitions you need.

@andy-ms I am not so familiar with typescript compiler, it internals and how it uses types library, so I am not quite sure what to set in the lib section here? And why? Please advise.

@dozer75 check out this link: [typescript compiler options].(https://www.typescriptlang.org/docs/handbook/compiler-options.html)

If you are modifying your tsconfig.json file, add a property of lib with an array of strings specifying which libraries to include. For me, I was using @types/core-js in a node server environment (with target es5, i.e. my typescript was being compiled to es5 for production) so I just added "es2015" and everything worked fine. It looks like if you are in a browser environment, adding "dom" will give you standard javascript window and stuff like that too.

By adding

"lib": ["es2017", "dom"]

to my compilerOptions in tsconfig.json solved this issue for me.

thanks @andy-ms

@DrDanRyan typescript documentation says that using es5 as a target adds DOM,ES5,ScriptHost to libs. So this should not be needed.
@Narven when adding es2017 to your lib you don't need core-js typings anymore. I wonder why you don't get duplicate identifiers then.

I'm a bit confused why core-js typings suddenly depend on another set of libraries. That doesn't look like the right solution to me.

@DaSchTour I think that lib: ["dom", "es5", "scriptHost"] is the default used for target es5 if you don't specify a lib property yourself. At least that is my understanding, and that would be the reason why you don't get duplicate identifiers when you speicfy lib: ["es2015", "dom"] yourself.

Also the lib option is a replacement for using @types/core-js as opposed to a dependency.

@DrDanRyan it's definitely not a replacement! lib for ES2017 will contain way more than @types/core-js which will hide compile errors when using features not polyfilled by core-js

That's why I am using "es2015" which works for a node server...

The problem still exists. lib contains more than core-js so I don't think that typings for core.js should "extend" lib.

I think we are talking past each other here. All I am saying is that after putting lib: ["es2015"] in my tsconfig.json that I don't need to use @types/core-js anymore so I uninstalled it and now just use the compiler flag.

Cross-linking this with PR that caused that: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/15108

Putting lib: ["es2015"] did not solve the issue for me.

I still get

error TS2693: 'Promise' only refers to a type, but is being used as a value here.

I've tried adding everything:

  "lib": [
    "es5",
    "es2015",
    "es2017",
    "dom",
    "scripthost"
  ],

and still get the error

Can you provide the code that is failing?

I ended up solving it like this:

{
  "compilerOptions": {
    "target": "es6",
    "module": "es6",
    ...
  },
  "lib": [
    "ES5",
    "ES2015",
    "DOM",
    "ScriptHost"
  ]

and removing @types/core-js

@dmitriid do not know why, but the same lib value worked for me.

Here is my entire tsconfig.

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "es5",
      "es2015",
      "es2017",
      "dom",
      "scripthost"
    ],
    "module": "commonjs",
    "experimentalDecorators": true,
    "sourceMap": true
  }
}

Probably, I have solved my problem and taking back my upvote from the original post.

Is using the "lib" configuration the proper long-term solution, or will @types/cores-js get fixed so it can be used the same as previously?

@PrimalZed I don't think that using lib is a proper solution at all, because it introduces features that might not be available through core-js. So lib and @types/core-js will never contain the same set of methods and core-js will always contain less than lib.

@DaSchTour let's look at the example:

  • There is a library X, that uses ES6 Map and it is typed using es6 lib definitions
  • In order so support old browsers you have imported core-js polyfill in your code before importing X.

Third-party libraries doesn't know anything about actual polyfill implementation so polyfill should provide identical definitions on order to avoid bugs like this https://github.com/DefinitelyTyped/DefinitelyTyped/issues/15104

@just-boris and then there is project Y and while using core-js and compiling to es5 with es6 lib a developer sees that strings have a function called normalize. Great 🎉 let's use it, it's exactly what I searched for. And some weeks later testing on IE11 and Safari 9 we see strange errors we hoped to avoid by using TypeScript 🤔
Oh and suddenly we can use Proxy with ES5 on IE11. Nice!
So polyfill have to implement full, 100% support for ES6 to avoid bugs and allow safe usage. 100%, 99,999% is to less as lib will reveal features that are not polyfilled. So let's say bye bye core-js 😢

On my end I ended up upgrading to @types/[email protected] and updating my tsconfig to this thus keeping compatibility with IE 11.

"lib": [
      "dom",
      "dom.iterable",
      "es2015",
      "scripthost"
    ],

By adding

"lib": ["es2017", "dom"]

to my compilerOptions in tsconfig.json solved this issue for me.

thanks @Narven

@just-boris your comment worked for me, ty!

I needs this to work for "target es5", using lib is a hack and just has a bad-smell overall.

The suggested way is to use @types/core-js, which unfortunately doesn't work for simple code like

let p = Promise.resolve( [ 1, 2, 3 ] );
p.then( function( v ) {
  console.log( v[ 2 ] ); // 1
} );

@andy-ms / @mhegazy
If I may, I'd like to resurface wrote on #15108:

Isn't the point of the Typescript definition files to describe what packages provide? I believe the definition should be accurate to the package, not the environment. Particularly with core-js, if somebody's using it, e.g., import 'core-js', they're conceivably doing so because they're shimming their environment, no?

An important reason why people use type definitions is to surface issues at compile time instead of at runtime. It is actually very important that core-js definitions represent what core-js is doing specifically because it does not provide a perfect polyfill for es2015/es2016/es2017. It's for that reason—particularly for libraries like core-js—that the environment libs need to be a separate matter, i.e., the polyfill might not match the standard.

Generating breaking changes across projects because of changes like this cannot be taken as lightly as demonstrated here. For one, it's hard enough to keep track of the impact of upgrading @types packages because they don't follow semver (which on its own isn't okay, regardless of the non-standard conventions used by DefinitelyTyped), but it's even harder if they're not even actually reflecting the library that you're working with. These practices negate in part the power, usefulness and ultimately the good experience that Typescript itself intends to provide to developers.

I was able to fix my compile error by adding the following to my tsconfig.json.

    "target": "es5",
    "lib": ["es2015", "dom"]

What is really stupid about this solution, is that without including "dom", TypeScript will error out when Promise is used.

You may also get these errors if your build isn't setup properly.

I am using gulp + gulp-typescript and didn't setup the typescript build process to take tsconfig.json into account.

So try this:

gulp.task('typescript', function () {
  var tsProject = ts.createProject(`${sourceRoot}/tsconfig.json`);
  return gulp.src([`${sourceRoot}/**/*.ts`])
    .pipe(tsProject())
    .pipe(gulp.dest(`${destinationRoot}`));
});

This may help in conjunction with other responses by people :smile:

By adding

"lib": ["es2015", "dom"]
to my compilerOptions in tsconfig.json solved this issue for me.

Such as @elusive adding the "lib" property to my tsconfig.json with the specified values fixed the compilation issue.

However it looks like a hack.

Any cleaner solution on its way?

I've the impression the changes that led to this issue spilt developer community. One part changed their tsconfig.json the other part set the typings version to an older release.

@DaSchTour : in my case I used the trick for the tsconfig.json because it's only for an example for Frint

But for a real project, a real solution should be found. Couldn't we update and fix core-js ?

I am using the latest everything and none of the lib examples worked for me :(

I'm seeing this error too. It doesn't break everything but it annoys me seeing those little red lines on compilation.

They go away with:

"target": "es5"
...
"lib": ["es5","dom","scripthost","es2015"]

Technically the error went away with just "lib": ["es2015","dom"], but if you look at the TS compiler options, the default lib injections for a target of es5 are "es5", "dom","scripthost", and I didn't want to lose the defaults.

However, with this change I noticed significant lag/bugs in my program's responses compared to before I added the lib option, so I've taken it out. A real solution to this would be awesome!

Just an FYI, if you are seeing these problems when trying to get NG2 to work, all of these problems go away when you use Angular CLI.

This is the tsconfig that Angular CLI creates:

"compileOnSave": false,
  "compilerOptions": {
    "outDir": "wwwroot/js/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2016",
      "dom"
    ]
  }

I have let this open for a long time now, because all things that are written here are in my opinion workarounds, not solutions.

Isn't this anything that is going to be solved in the definition package itself?

As other states, by adding lib entry in tsconfig it works, but it also renders this package uneccessary, why do we need this package at all if it can be handled by just setting lib (which we must do anyway)?

My solution was to add lib: [ "es2015", "dom" ] in my ts.config and I also removed this library since it wasn't needed when I added the lib entries.

If the owners of this package doesn't want to do anything with this. I suggest you to close this issue with a comment why and how to do it correctly so that everyone knows what to do.

This solution had worked for me on windows machine.

"lib": ["es2017", "dom"]
to my compilerOptions in tsconfig.json solved this issue for me.

thanks @andy-ms

@Jtreu Thank you for your response relating gulp on this topic.

That was the issue on the very start of this project

https://github.com/toni-rmc/laravel-angular-integration

and your response help solving it.

I've submitted a PR to roll this back to the correct form: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/19531

@dozer75 @ctlong @DaSchTour @rajinder-yadav @jackTheRipper

So for example, If I'm shimming only ES6 Symbols with core-js the included libraries should be (at least): es5,dom,es2015.symbol

Can anyone confirm if my interpretation is correct? Thanks!
/cc @andy-ms

@cvsguimaraes That should be correct.

This still is broken? Im' getting error TS2304: Cannot find name 'PropertyKey'. and more on 0.9.43

UPDATE: Nevermind, I didn't realize providing a source file to compile on the command line like tsc priotractor.ts would prevent it from reading the `tsconfig. I created a new tsconfig file just for my protractor test which only includes the one file I'm looking to compile and it works fine now.

Here's my config if it helps anyone

{
   "compileOnSave": false,
   "compilerOptions": {
      "baseUrl": ".",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": [
         "node_modules/@types"
      ],
      "lib": [
         "es2016",
         "dom"
      ]
   },
   "files": [
      "./config/protractor.config.ts"
   ]
}

In case someone else can learn from my mistake. Make sure you're editing a tsconfig.json in the right directory!

After a lot of head banging I noticed that I was editing the config in my project root instead of the config in root/src which is what I had opened in VSCode. After making the recommended changes there it works.

Updating TypeScript to v2.6.1 & setting it as a version for VS Code solved the issue for me.

@IAMtheIAM fixed it for me, thanks

Was trying most of the compilerOptions settings listed here with little to none success throughout a couple of days. Darn, I even upgraded typescript package on my OS!

The solution was too easy to notice: do not pass TS files to tsc directly, but rather specify them in tsconfig.json and just call tsc.

@shybovycha As much as that fixes the problem, the docs specify you can and should be able to pass the file into the command directly. Without this mini 'fix', I would still be getting the errors otherwise. I have the following versions:

    "@types/core-js": "2.5.0"
    "core-js": "2.5.7"
    "typescript": "3.1.6"
Was this page helpful?
0 / 5 - 0 ratings