I am trying a simple class in typescript using Visual Studio 2015. Somehow, the TypeScript doesn't recognize getElementById! The following is the code I am using which I downloaded from another thread.
class TypeSearch {
searchKey = document.getElementById('search').addEventListener('click', () => this.search());
search() {
alert("i am clicked");
}
}
The error is "Can't resolve symbol getElementById"
Thanks
You are missing the typings (type definition) for DOM.
You need to add the dom lib:
https://www.typescriptlang.org/docs/handbook/compiler-options.html
// tsconfig.json
{
"compilerOptions": {
"lib": [
"dom"
],
...
}
}
Have you successfully transpiled your typescript file into a Javascript file and caught the described error at runtime? If not, i.e. you get transpilation error, just add declare var document: any.
Related
I created a new Vue app via npm init vue#latest with the following setup
I replaced the content of the App.vue file with
<script setup lang="ts">
const e = new Error("something failed");
console.log(e.cause);
</script>
I get the following error
Property 'cause' does not exist on type 'Error'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2022' or later.ts(2550)
Based on the docs the cause property should exist. I added "lib": ["ESNext"], to tsconfig.vitest.json, tsconfig.config.json and tsconfig.app.json ( I don't know which one needs it ). Then I get the error
Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.ts(2584)
so I add it too and it seems to be fine now. It feels wrong to me since this already is a web project and I don't think the basic setup is lacking essential features...
So are there any better solutions for this?
I also tried to set this field inside the tsconfig.json file like so
{
"files": [],
"compilerOptions": {
"lib": ["ESNext", "DOM"],
},
"references": [
{
"path": "./tsconfig.config.json"
},
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.vitest.json"
}
]
}
but this didn't work, then cause does not exist on type Error again.
I just want to have access to the cause property of Error inside a new Vue project :)
You need to first set an cause for the error and later you can console log it.
const myError = new Error('Databse status:503')
myError.cause = 'Database failed to connect!'
console.log(myError.cause)
I am trying to run a Typescript program that seems to always break when it reaches a line of code where a class calls its parent using super.
class A extends B {
constructor(endpoint: string) {
super(endpoint) // error here
}
}
The error I am getting is:
TypeError: Class constructor Connection cannot be invoked without 'new'
(associated_js_file.js)
var _this = _super.call(this, endpoint) || this
I have seen previous questions that are similar but I have tried their solutions to no avail.
What I have done:
Changed my Node version from v18.6.0 to v16.16.0 (someone told me that the program was working for them and this was the only difference in our Node or ts-node versions).
I read in other questions that ts-node has a default target of es5, which causes an error when it is compiled to Javascript. I have checked the target using ts-node --showConfig, where it shows the target is es6.
For added measure, I added a tsconfig.json file that looks like this:
{
"compilerOptions": {
"target": "ES6"
}
}
and ran ts-node --project tsconfig.json main.ts.
Why is my program still having the same error?
I have a problem I cannot solve with typescript 4.0 to create a declaration file (d.ts) for a jsdoc annotated javascript library in commonJS format.
If one or more objects is required from more than a module when I run the typescript compiler to create the d.ts files I get this error:
index.js:1:1 - error TS9006: Declaration emit for this file requires using private name 'Rectangle' from module '"/Users/gabry/projects/ts-test/rectangle"'. An explicit type annotation may unblock declaration emit.
1 const {Rectangle} = require('./rectangle');
~~~~~
Found 1 error.
I can "fix" it by adding "export" before class in rectangle.js, but in that way the code is not more runnable under node.js...
I've seen there is a bug in typescript about something similar https://github.com/microsoft/TypeScript/issues/9865 , that should be solved in typescript 4.1 beta, but also installing that version of typescript I have the same problem, maybe something is wrong in the way I use commonJS require/module.exports?
Here is a sample:
index.js
const {Rectangle} = require('./rectangle');
class Render {
constructor() {
/**
* Object list
* #type {Rectangle[]}
*/
this.objects = [];
}
/**
* Adds a rectangle
*
* #returns {Rectangle} the rect
*/
addRectangle() {
const obj = new Rectangle();
this.objects.push(obj);
return obj;
}
}
module.exports = { Render }
rectangle.js
class Rectangle {
constructor() {
console.log("I'm a rectangle!");
}
}
module.exports = { Rectangle };
this is the tsconfig.json:
{
// Change this to match your project
"files": ["index.js"],
"compilerOptions": {
"allowJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "types",
"strict": false
}
}
I tried adding/changing tons of tsconfig.json params (target, module, moduleResolution...) without success...
I can run it without problems from a simple test script with node:
test.js
const {Render} = require("./index");
let render = new Render();
render.addRectangle();
console.log("Objects", render.objects);
node test.js
...returns as expected:
I'm a rectangle!
Objects [ Rectangle {} ]
This is now fixed in the released version of typescript 4.1, it was, indeed, a bug of the typescript compiler that occurred when emitting only declarations, the first betas of typescript 4.1 still had the bug, but a certain point the nightly began to be fixed (see the bug in the original question for detailed history) and eventually the final, working, v4.1 was released on the npm registry.
So if someone stills has this problem it can simply update his typescript dependency to the latest stable version ( ^4.1 ).
I am trying to remove duplicates in an array with new Set gives an error "new Set(names).slice is not a function"
const names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
const uniq = [ ...new Set(names) ];
console.log(uniq);
Here is the code on stackblitz
I was able to fix the error by adding a tsconfig.json in the root of the project. It is a super simple config:
{
"compilerOptions": {
"target": "es6"
}
}
What is happening is that TypeScript is compiling to an es3 version of javascript which is the default if no target is configured as shown here (see --target).
When your code goes through the build phase and is translated from TypeScript to JavaScript, the second line you posted becomes:
var uniq = new Set(names).slice();
Personally I would consider that a TypeScript bug but I never use TypeScript so I can't say for sure.
edit — actually I don't think it happens unless you're targeting ES5.
Summernote is a jQuery plugin, and I don't need type definitions for it. I just want to modify the object, but TS keeps throwing errors. The line bellow still gives me: "Property 'summernote' does not exist on type 'jQueryStatic'." error.
(function ($) {
/* tslint:disable */
delete $.summernote.options.keyMap.pc.TAB;
delete $.summernote.options.keyMap.mac.TAB;
/* tslint:enable */
})(jQuery)
Edit:
Here is my tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es5",
"allowJs": true,
"noUnusedParameters": true
},
"include": [
"js/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
As of Typescript 2.6, you can now bypass a compiler error/warning for a specific line:
if (false) {
// #ts-ignore: Unreachable code error
console.log("hello");
}
Note that the official docs "recommend you use [this] very sparingly". It is almost always preferable to cast to any instead as that better expresses intent.
Older answer:
You can use /* tslint:disable-next-line */ to locally disable tslint. However, as this is a compiler error disabling tslint might not help.
You can always temporarily cast $ to any:
delete ($ as any).summernote.options.keyMap.pc.TAB
which will allow you to access whatever properties you want.
#ts-expect-error
TypeScript 3.9 introduces a new magic comment. #ts-expect-error will:
have same functionality as #ts-ignore
trigger an error, if actually no compiler error has been suppressed (= indicates useless flag)
if (false) {
// #ts-expect-error: Let's ignore a compile error like this unreachable code
console.log("hello"); // compiles
}
// If #ts-expect-error didn't suppress anything at all, we now get a nice warning
let flag = true;
// ...
if (flag) {
// #ts-expect-error
// ^~~~~~~~~~~~~~~^ error: "Unused '#ts-expect-error' directive.(2578)"
console.log("hello");
}
Playground
What do TypeScript developers recommend?
#ts-ignore and #ts-expect-error are like a sledgehammer for compile errors. TypeScript developers recommend more fine-grained, narrow-scoped typesystem solutions for most cases:
We added ts-ignore with the intent that it be used for the remaining 5% that can't be suppressed by any existing type system mechanics [...] there should be very very very few ts-ignores in your codebase[.] - microsoft/TypeScript#19139
[...] fundamentally, we believe you shouldn't be using suppressions in TypeScript at all. If it's a type issue, you can cast out of it (that's why any, casting, and shorthand module declarations exist). If it's a syntax issue, everything is awful and we'll be broken anyway, so suppressions won't do anything (suppressions do not affect parse errors). - microsoft/TypeScript#19573
Alternatives for question-case
▶ Use any type
// type assertion for single expression
delete ($ as any).summernote.options.keyMap.pc.TAB;
// new variable assignment for multiple usages
const $$: any = $
delete $$.summernote.options.keyMap.pc.TAB;
delete $$.summernote.options.keyMap.mac.TAB;
▶ Augment JQueryStatic interface
// ./global.d.ts
interface JQueryStatic {
summernote: any;
}
// ./main.ts
delete $.summernote.options.keyMap.pc.TAB; // works
In other cases, shorthand declarations / augmentations are handy utilities to compile modules with no / extendable types. A viable strategy is also to incrementally migrate to TypeScript, keeping not yet migrated code in .js via allowJs and checkJs: false compiler flags.
You can simple use the following just before the line:
// #ts-ignore
I used // #ts-ignore:next-line right before the error.
If you're using eslint to perform your check or fix you can disable a line by adding this on top of the line
// eslint-disable-next-line #typescript-eslint/<RELEVANT_ESLINT_RULE>