Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to over power TS and ignore specific error by developer #9448

Closed
born2net opened this issue Jun 30, 2016 · 150 comments
Closed

Ability to over power TS and ignore specific error by developer #9448

born2net opened this issue Jun 30, 2016 · 150 comments
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@born2net
Copy link

born2net commented Jun 30, 2016

A developer should be able to add a comment above a ts error such as

/// TS_IGNORE
let a:string = 1

and have the compiler not report that error...
there are certain scenarios the developer knows best and want to quiet down the error reports.

kind of like :any

regards

Sean

@fluffywaffles
Copy link

fluffywaffles commented Jun 30, 2016

Agreed. Longing for something like Java's @SuppressWarnings, in particular for the case described here:

The following:

const typeMetadataKey = Symbol('type');

function type(name: string): PropertyDescriptor {
 return Reflect.metadata(typeMetadataKey, name);
}

Produces the error: Unable to resolve signature of class decorator when called as an expression..

When used as below:

class Person {
  @type('string')
  firstName: string;
}

The decorator does work as expected and will compile but gives the error above.

If you have thoughts on how this might be resolved happy to dig into it if someone would like to point to the right direction.

@rozzzly
Copy link

rozzzly commented Jun 30, 2016

Just cast it (cast isn't official term, but same concept)

const foo: string = 7 as any;

Is that what your looking for?

@born2net
Copy link
Author

I just gave an example, not really a case (I know all about casting) , I do have other cases such as
super being called after first line of constructor and other issues...

  • will make transition into TS easier from JS + sometime you change a lib and get tons of errors and you just want to clean things up as you know as the developer for the reason...

this is an important feature

@rozzzly
Copy link

rozzzly commented Jun 30, 2016

So something like // tslint:disable?
Possibly even letting you turn on/off specific checks tsc performs?
eg: const FooBar: string = 'rozzzly'; // tslint:disable-line camelcase

@born2net
Copy link
Author

that would be awesome...

@rozzzly
Copy link

rozzzly commented Jun 30, 2016

I don't know... I think that might be out of the scope of tsc. That's what linters are for.

@born2net
Copy link
Author

there has to be able to "shut it up" :)

@fluffywaffles
Copy link

fluffywaffles commented Jun 30, 2016

I think there's a case to be argued for suppressing errors/warnings on "experimental" features, like decorators, where the API is a bit volatile and the errors may not always be accurate. You get a (very specific) version of this just using the tsconfig "experimentalDecorators" field, but it only suppresses one type of warning.

To play my own devil's advocate, this could encourage new users of TypeScript to suppress warnings they do not understand instead of learning why the warning occurs. And with experimental features, everyone is sort of a new user - having the ability to suppress errors could make users complacent with bugs in new features, instead of opening issues.

Ultimately, I still want my Syntastic output to be clean. Which means suppressing the error. Of course, that would be after I open the issue for a possible bug and try to learn more. ;)

@mhegazy
Copy link
Contributor

mhegazy commented Jun 30, 2016

The problem with "shutting it up" is you do not know what you get out of "it". so is let a:string = 1 a number or a string?, what if there is another declaration of a, does it merge or not? what if some one captured the type of this variable e.g. return {a} ; , should they be assignable to { a : number } or { a: string }, or both.

one fundamental thing, errors are all ignoble. errors do not block the generation of outputs, nor the tooling.

There are different mechanisms to allow you to suppress checking of certain parts of your code, e.g. any, type assertions (casts), and ambient declaration.

so for instance, if you have a library that has "invalid" definition, you can just remove it, and replace it with declare module "blah" { export = any }. or declare var $: any and you are good to go.

As i usually reply to these requests, i think your problem is not in suppressing the error. the real issue is you got an error that you do not find useful. suppress that does not solve the underlying problem it just covers it, and has ramifications of an inconsistent state with no warning. The right solution is to know what is the error you are getting? what library is it? and why the compiler is giving you an unuseful error...

And for this we need to know more about your use case.

We have done some work in TS 2.0 to resolve some of these underlying issues, for instance;

@mhegazy mhegazy added the Discussion Issues which may not have code impact label Jun 30, 2016
@zpdDG4gta8XKpMCd
Copy link

just use any, this is how "shut it up", merits of doing so (or actually a lack of thereof) is a different question

let x: PieInTheSky = <any> 'cake is a lie';

@born2net
Copy link
Author

born2net commented Jul 1, 2016

ok but again, the issue is not specifically on casting

@zpdDG4gta8XKpMCd
Copy link

<any> gives you vanila javascript with 100% freedom from all annoying things of TypeScript, so what else do you need?

@born2net
Copy link
Author

born2net commented Jul 1, 2016

in my case I call super not as fisrt line of constructor and need to quiet the error

@rozzzly
Copy link

rozzzly commented Jul 2, 2016

Instead of trying to force it to accept an antipattern, why not write try something like this:

ClassA.ts

class A {
    constructor() {
        this.init();
    }
    protected init() {
        // does nothing by itself
    }
}

ClassB.ts

class B extends A {
    constructor() {
        super();
        console.log('rest of code from B\'s constructor');
    }
    protected init() {
        console.log('this runs before the rest of code from B\'s constructor');
    }
}

This is what makes typescript so awesome, and also annoying. It forces you to write better code and it makes you a better developer. Converting a project is not fun; you might consider it to be a developer's "initiation" or perhaps, "trial by fire." 😆 But you learn a lot, and its totally worth it imho.

@kitsonk
Copy link
Contributor

kitsonk commented Jul 4, 2016

in my case I call super not as fisrt line of constructor and need to quiet the error

And make your code incompatible with ES6... Which is exactly why the main purpose of TypeScript is to take 👣 🔫 out of your hands.

If TypeScript is not interpreting something right, then it should be fixed versus "worked around". Now there are a few things where TypeScript is acting more like a linter and there is not yet a concept of "error" versus "warning". I can see suppressing warnings when they do come. Things like code after return and unused parameters should be warnings in my opinion, because they are syntactically correct (though stupid).

@DethAriel
Copy link

DethAriel commented Oct 20, 2016

here's another case where I would love to have this feature:

interface Animal {
  numberOfLegs: number;
  // a gazillion more properties
}

class Dog implements Animal {
  breed: string;

  constructor(animal: Animal, breed: string) {
    Object.assign(this, animal);
    this.breed = breed;
  }
}

Right now there's an error from ts:

[ts] Class 'Dog' incorrectly implements interface 'Animal'
Property 'numberOfLegs' is missing in type 'Dog'

As you can see, the compiler is totally wrong, but I don't want to (and I shouldn't be forced to) copy all the properties from the interface just for the compiler's sake.

@aluanhaddad
Copy link
Contributor

@DethAriel Basically what you're asking for is a way to express post condition side effects in the type system. That's interesting but I have a feeling it would lead to some terribly convoluted code.

@DethAriel
Copy link

@aluanhaddad Yup, I totally get that. But still, I do not see a non-ugly workaround for that except for copy-pasting the interface members, which is non-ideal at the very least. That's why I think that having the ability to shut up the compiler error output makes sense - we're all smart people here, and the compiler should trust us when we tell it to

@mhegazy
Copy link
Contributor

mhegazy commented Oct 21, 2016

Just use an interface+class combo

interface Animal {
  numberOfLegs: number;
  // a gazillion more properties
}

interface Dog extends Animal {
}

class Dog  {
  breed: string;

  constructor(animal: Animal, breed: string) {
    Object.assign(this, animal);
    this.breed = breed;
  }
}

@DethAriel
Copy link

Thx, @mhegazy , that worked indeed

@sunny-g
Copy link

sunny-g commented Nov 1, 2016

What if the error can't be <any>ed away?

Im using the experimental bind syntax as discussed here #3508 and aside from not using it, I'm otherwise unable to get the compiler to ignore the error on each line before each :: operator (TS1128: Declaration or statement expected)

@mhegazy
Copy link
Contributor

mhegazy commented Nov 1, 2016

Im using the experimental bind syntax

this is really more than dismissing one warning. The parser does not support it, so the resulting tree is completely wrong, all of the compiler features from this point on will not work, so no type inference, no compatibility checks, no formatting, no completion, nothing. so you would be better off ignoring all errors, or just working in a .js file.

@zeeshanjan82
Copy link

I am currently converting a huge JS project into typescript and after doing the conversion when I run gulp build command I see around 2000 TS errors during compilation and majority of the errors are related to Property not defined on a class or Module not defined. I think there must be some way to suppress these types of errors as the output JS files are getting generated.

@108adams
Copy link

108adams commented Nov 3, 2016

This is exactly my case as well, I convert an app built with pre-ES6 modules-as-properties design, so I have a HUGE app.namespace1.namespace2.something.views.view -like global object.

I rewrite some part of it and I DO rely on the global app.* object and its different sub-elements in my code. All I get is a mass of "Cannot find namespace 'app'" warnings.

I have refactored all my global dependencies to a globalProxy.ts, so this is the only place I get the warnings, but it would be AWESOME to add a //TS-NO-WARNINGS at the top of this file to clean up the console from the obvious messages...

@mhegazy
Copy link
Contributor

mhegazy commented Nov 3, 2016

TS errors do not block the code generation. You could choose to ignore them, but what these are telling you is that the compiler can not assert the correctness of your code.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Nov 3, 2016

@zeeshanjan82 why not use --allowJs and migrate file by file? With that setup you won't get type errors from JavaScript sources. You can also use an ambient wildcard declaration to suppress module resolution errors like
globals.d.ts

declare module '*';

@adamreisnz
Copy link

Here's another use case for error suppression.

The maintainers of the moment library forgot to add isoWeek as a valid string to the parameter enum for startOf and endOf methods. It was fixed in a subsequent release, but in doing so they completely refactored the way these units are handled, which would cause too much re-work on our end.

So we fixed the version of moment in place, but now we essentially can't use isoWeek because of TS throwing errors. So stuck between a rock and a hard place at the moment.

@mhegazy
Copy link
Contributor

mhegazy commented Nov 30, 2016

you could just add a local copy. say something as simple as:

// ./overrides/moment.d.ts
declare module "moment";
// tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "baseUrl": ".",
        "paths": {
            "moment": ["overrides/moment.d.ts"]  // override definition for moment
        }
    }
}

now the compiler will be checking against your local copy of override/moment.d.ts instead of the one coming with the package. obviously this can be a local copy of moment declaration file, or a small set of things you need.

@amiraliakbari
Copy link

I am trying to manually set window.console for IE9 to prevent errors on console.log usage:

if (!window.console)
    window.console = {};

But I get error TS2540: Cannot assign to 'console' because it is a constant or a read-only property. Are there any workaround for these use cases?

@fabiandev
Copy link

@amiraliakbari You can assert window as any type, which effectively lets you opt out of type checks:

(window as any).console = {};

@b264
Copy link

b264 commented Aug 29, 2017

this worked for me to override/disable console.log globally -- Notice that Project.logging was defined before this

(window.console as any).___real_log = window.console.log;
window.console.log = function(args) {
  if (Project.logging) return (window.console as any).___real_log(args);
  return;
};

This was also much cleaner than putting if statements all over my code as I can just use console.log as normal

@RyanCavanaugh RyanCavanaugh added In Discussion Not yet reached consensus Suggestion An idea for TypeScript and removed Discussion Issues which may not have code impact labels Aug 29, 2017
@ahejlsberg ahejlsberg added the Fixed A PR has been merged for this issue label Sep 13, 2017
@ahejlsberg ahejlsberg added this to the TypeScript 2.6 milestone Sep 13, 2017
@mhegazy mhegazy removed the In Discussion Not yet reached consensus label Sep 19, 2017
@ghost
Copy link

ghost commented Oct 12, 2017

As mentioned in #19109 we still don't have the ability to suppress a specific error.

@ghost ghost reopened this Oct 12, 2017
@mhegazy mhegazy closed this as completed Oct 12, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Oct 12, 2017

As mentioned in #19109 we still don't have the ability to suppress a specific error.

I think basic scenario outlined in this issue has been addressed. we can create a new issue to track global error suppression using error number. We have been reluctant to use error codes in such way because they lack expressiveness.

@ghost
Copy link

ghost commented Oct 12, 2017

Created #19139.

@Lonli-Lokli
Copy link

This instruction works only per file, right? Is it possible to make it work over folder?

@ghost
Copy link

ghost commented Oct 17, 2017

The instruction is supposed to work for a single line at a time. If you're seeing a lot of compiler errors in your project, you might check that you should have less strict compiler options, such as leaving noImplicitAny off (i.e., variables are implicitly any if not annotated). You could also leave some files as JS and set allowJs on but checkJs off.

@webia1
Copy link

webia1 commented Jan 10, 2018

Why did you close this issue? The solution is still missing! Why do you have meaningless discussions for 2 years instead of integration a proper error-suppressing-possibility?

@ghost
Copy link

ghost commented Jan 10, 2018

@webia1 You might be interested in #19139 which is still open.

@miltonbecker
Copy link

miltonbecker commented Mar 20, 2018

(Adding this comment here as it might be useful for those who stumble upon this issue, as I did)

I ran across #21602 and it might be the solution.

Just add // @ts-ignore to your code (or even // @ts-ignore <some code error> to ignore only the specified error).

Tested it here with TypeScript 2.7.2 and it works!

@RyanCavanaugh
Copy link
Member

(or even // @ts-ignore to ignore only the specified error).

#21602 was not merged. You can't ignore only certain errors.

@miltonbecker
Copy link

@RyanCavanaugh you're right! I've updated my comment. Thanks!

@tomshaw
Copy link

tomshaw commented May 19, 2018

Arrived here looking to suppress error TS2339.

document.getElementById('theme-admin').disabled = false; /* tslint:disable */
document.getElementById('theme-member').disabled = true; /* tslint:disable */

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests