Compile problem with LitElement TS example - polymer

Hello Polymer Community:
New user here having a bit of trouble with lit-element with TS, and not sure why.
I have TS setup and working fine (compiled other TS examples).
Did npm install lit-element per Getting Started page.
https://lit-element.polymer-project.org/guide/start
Trying the TS example under the section: "Use LitElement TypeScript decorators" and getting all kinds of bad happening.
tsc my-element.ts results in complete fail:
my-element.ts:14:14 - error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
14 export class MyElement extends LitElement {
my-element.ts:20:3 - error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
20 foo = 'foo';
node_modules/lit-element/lib/updating-element.d.ts:102:38 - error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
102 export declare type PropertyValues = Map<PropertyKey, unknown>;
node_modules/lit-html/lib/parts.d.ts:18:63 - error TS2304: Cannot find name 'Iterable'.
18 export declare const isIterable: (value: unknown) => value is Iterable<unknown>;
node_modules/lit-html/lib/render.d.ts:16:29 - error TS2583: Cannot find name 'WeakMap'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
16 export declare const parts: WeakMap<Node, NodePart>;
node_modules/lit-html/lib/template-factory.d.ts:56:28 - error TS2583: Cannot find name 'WeakMap'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
56 readonly stringsArray: WeakMap<TemplateStringsArray, Template>;
node_modules/lit-html/lib/template-factory.d.ts:57:25 - error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
57 readonly keyString: Map<string, Template>;
node_modules/lit-html/lib/template-factory.d.ts:59:38 - error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
59 export declare const templateCaches: Map<string, templateCache>;
Found 8 errors.
I have no idea how to press forward and really want to work with web components and TS for a new project.
My tsconfig.json is:
{
"compilerOptions": {
"target": "es6",
"module": "es6"
}
}
I have also tried with no tsconfig file. Same results.
Please kind people help point me in the right direction.
Thank you.
David

I had a similar problem, using version 3.9.3 of the TypeScript compiler, which I managed to solve by having this tsconfig.json:
{
"compilerOptions": {
"target": "es2015",
"lib": ["es2015"],
"module": "commonjs",
"experimentalDecorators": true
}
}

You need to include the dom library in tsconfig.json:
{
"compilerOptions": {
...,
"lib": [
...,
"dom"
]
}
}

Related

Cannot compile namespaces when the '--isolatedModules' flag is provided - WebStorm

I've this error, I'm using WebStorm.
/src/Component/Professori.tsx
Type error: Cannot compile namespaces when the '--isolatedModules' flag is provided. TS1208
I've also added the flag marked as false into tsconfig.json in this way
"isolatedModules": false
You should use the export keyword post to your component declaration, that in order to be aligned to the ECMAScript standards when declaring a public component. so it should look like that:
const professori = (props: any) => (
...
);
export default professori;
this will resolve the error.

CKEditor 5 throws Cannot read property 'create' of undefined in Angular6 project

I've created a project using JHipster and trying to create a WYSIWYG rich text editor using CKEditor 5. I've done the below steps by using the following link to create an editor.
npm install --save-dev #ckeditor/ckeditor5-angular
npm install --save-dev #ckeditor/ckeditor5-build-classic
Imported #ckeditor/ckeditor5-angular and added in imports in my module.js
Imported #ckeditor/ckeditor5-build-classic and created a variable public Editor: ClassicEditor; in my component
Used following code in html
Blockquote
<ckeditor [editor]="Editor" data="<p>Hello world!</p>"></ckeditor>
When I go to the page I added throws the following error which I got it from the browser developer tools console.
ERROR TypeError: Cannot read property 'create' of undefined
at CKEditorComponent.createEditor (ckeditor-ckeditor5-angular.js?076d:187)
at eval (ckeditor-ckeditor5-angular.js?076d:96)
at ZoneDelegate.invoke (zone.js?d135:388)
at Zone.run (zone.js?d135:138)
at NgZone.runOutsideAngular (core.js?09c9:3784)
at CKEditorComponent.ngAfterViewInit (ckeditor-ckeditor5-angular.js?076d:95)
at callProviderLifecycles (core.js?09c9:9568)
at callElementProvidersLifecycles (core.js?09c9:9542)
at callLifecycleHooksChildrenFirst (core.js?09c9:9532)
at checkAndUpdateView (core.js?09c9:10468)
I'm just wondering if that's an issue with CKEditor 5 or did I miss any steps?
You have the following code under the link:
export class ArticleUpdateComponent implements OnInit {
public Editor: ClassicEditor;
// ...
}
While you should actually set the ClassicEditor to the Editor property, you only set it's type (which is actually wrong too, since the editor can have type typeof ClassicEditor).
What you should do is simple property assignment public Editor = ClassicEditor;, which will make the ClassicEditor available in the template under the Editor property.
This error can be also thrown when the import is incorrect - depending on the TypeScript configuration the import should look like import * as ClassicEditor from '#ckeditor/ckeditor5-build-classic'; or import ClassicEditor from '#ckeditor/ckeditor5-build-classic';.
Created a file src/app/typings.d.ts with below code
declare module '#ckeditor/ckeditor5-build-classic' { // or other CKEditor 5 build.
const ClassicEditorBuild: any;
export = ClassicEditorBuild;}
Inside your main app module, import CKEditorModule as below:
import { CKEditorModule } from '#ckeditor/ckeditor5-angular';
#NgModule({imports: [CKEditorModule]})
Now, add import to the component where that issue was occurring in say x.component.ts
import * as ClassicEditorBuild from '#ckeditor/ckeditor5-build-classic';
export class x implements OnInit { public Editor = ClassicEditorBuild;constructor() { } ngOnInit(): void {}}
Finally, add below code in your x.component.html
<ckeditor [editor]="Editor" data="<p>Hello, world!</p>"></ckeditor>
My solution was roughly the same as above, but as these didn't quite solve it, I tried:
public Editor: any = ClassicEditorBuild;
(adding : any)
which worked
If you have this issue even if you have this:
public Editor = BalloonEditor;
Check if you have in your template any call to the ckeditor component
For example:
<ckeditor formControlName="contenido"></ckeditor>
If you not set [editor]="Editor" it will produce same error.
try declaring this
public Editor: any = ClassicEditorBuild;
and in
file
../../../../node_modules/#ckeditor/ckeditor5-angular/ckeditor.component.d.ts
change CKEDITOR_VERSION: to any from string.

Typescript: how to get function name as string without TS2339 error

I found the following example in the Function.name documentation
const o = {
foo(){}
};
o.foo.name; // "foo";
The problem in typescript (typed here):
const o: { foo: () => void } = {
foo: () => {
}
};
o.foo.name;
comes when I want to retrieve
o.foo.name, where I will get an error
TS2339 (property "name" does not exist)
How can I deal with it, keeping the object typing?
I want to avoid having to cast the property "foo" like (<any>o.foo).name
PS: The use case is to keep the typing for further refactoring. For instance the following is safe to be refactored:
spyOn(o, (<any>o.foo).name)
While this one is not
spyOn(o, "foo")
PS 2: It seems retrieving function name could be problematic on ts: Get name of function in typescript
The problem is that this code only works for newer versions of Javascript. If you change the target on the typescript compiler settings to es2015 the problem goes away. If you target es5 the definitions for that version do not include the name property because it might not work on older Javascript runtimes.
If you are ok with targeting es2015, that is ok, if not you should come up with a different solution that works for es5.
If you are targeting an environment that supports this property but you don't yet trust the es2015 implementation for all features, you could just add the the Function interface the missing property. At the top level in one of your files you can redefine the Function interface, and this will be merged into the default definition, adding the extra property:
interface Function {
/**
* Returns the name of the function. Function names are read-only and can not be changed.
*/
readonly name: string;
}
Post ES2015, this:
const o: { foo: () => void } = {
foo: () => { }
};
console.log(o.foo.name);
should work just fine.
Check it in the Typescript Playground, and observe the produced JavaScript. You will see the common sections with the foo example you mentioned.
Here is the console, nice and clean:
Pre-ES2015, this wouldn't work and I think you would have to cast it, if targeting post-ES2015 is not an option.

Can I export an object using `export` as "`module.export`"

I think what I am asking for is not possible OOB, but I want to confirm.
We are in a process of upgrading to ES6 (using Babel). Project is a web-site, using AMD (requirejs). I would like to turn a utility module (foolib) into ES6, but consume it from either ES6 (using import) or existing ES5/AMD module.
// foolib.es6
export { // as expected, this doesn't work
method1: function () { ... },
value1: 123.456
};
// consumer1.es6
import foolib from "foolib";
// consumer2.js
define(["foolib"], function (foolib) {});
I understand that the solution is to change foolib.es6 as follows:
export function method1() { ... };
export let value1 = 123.456;
However in reality number of entries returned from foolib is ridiculous. So I was hoping there is a way to export existing object literal without rewriting every line.
Furthermore, I realize that this is most likely impossible, due to the differences between AMD import (using define) and import mechanism (later works with exports object that has values hanging off of it, including default value, while former expects a single value to be returned).
One possible solution that I think might work is to export my object as default from foolib.es6, and then tweak requirejs default loader to inspect imported value for being an esModule and return default value: value && value.__esModule && value.default || value. Should this work? (I'm still hoping there is an easier solution).
The syntax you are using to export the object is invalid because you are not giving the object a name, so it cannot be a named export, and you are not specifying that it is the default export, so it cannot be the default export. Change it to be the default export:
// foolib.es6
export default {
method1: function () {},
value1: 123.456
}
// consumer.es6
import foolib from "foolib";
console.log(foolib.value) //=> 123.456
You can use the babel-plugin-add-module-exports Babel plugin to reinstate a default export as the value of module.exports in Node-land.
And as you discovered, make sure you include this plugin before any other -modules- plugins, for example transform-es2015-modules-amd.
This might be late but alternatively you can use the named export as well which is a little different from the default approach that #sdgluck mentioned.
const method1 = function () {};
const value1 = 123.456;
export { method1, value1 };
I like this approach because you can import them directly like
import { method1, value1 } from 'foolib';
without reaching out to the default variable.

Babel error: Class constructor Foo cannot be invoked without 'new'

I am using babel to transpile.
I have class BaseComponent which is extended by class Logger.
When I run new Logger() in the browser, I am getting this error
Class constructor BaseComponent cannot be invoked without 'new'
the code that throws this is:
var Logger = function (_BaseComponent) {
_inherits(Logger, _BaseComponent);
function Logger() {
_classCallCheck(this, Logger);
return _possibleConstructorReturn(this, Object.getPrototypeOf(Logger).call(this, "n")); //throws here
}
Due to the way ES6 classes work, you cannot extend a native class with a transpiled class. If your platform supports native classes, my recommendation would be, instead of using the preset es2015, use es2015-node5, assuming you're on Node 5. That will cause Babel to skip compiling of classes so that your code uses native classes, and native classes can extend other native classes.
Another solution is to include { exclude: ["transform-es2015-classes"] } in .babelrc
presets: [
["env", { exclude: ["transform-es2015-classes"] }]
]
UPDATE: In the latest version of "env" preset plugin names have changed (e.g. it's now "transform-classes"). Use the "debug" option to inspect which plugins are included.