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

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

Comments

Projects
None yet
@born2net

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

This comment has been minimized.

Show comment
Hide comment
@fluffywaffles

fluffywaffles 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.

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

This comment has been minimized.

Show comment
Hide comment
@rozzzly

rozzzly 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?

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

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jun 30, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@rozzzly

rozzzly 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

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

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jun 30, 2016

that would be awesome...

that would be awesome...

@rozzzly

This comment has been minimized.

Show comment
Hide comment
@rozzzly

rozzzly Jun 30, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jun 30, 2016

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

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

@fluffywaffles

This comment has been minimized.

Show comment
Hide comment
@fluffywaffles

fluffywaffles 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. ;)

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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Jun 30, 2016

Contributor

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;

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 label Jun 30, 2016

@aleksey-bykov

This comment has been minimized.

Show comment
Hide comment
@aleksey-bykov

aleksey-bykov Jul 1, 2016

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';

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

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jul 1, 2016

ok but again, the issue is not specifically on casting

born2net commented Jul 1, 2016

ok but again, the issue is not specifically on casting

@aleksey-bykov

This comment has been minimized.

Show comment
Hide comment
@aleksey-bykov

aleksey-bykov Jul 1, 2016

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

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

@born2net

This comment has been minimized.

Show comment
Hide comment
@born2net

born2net Jul 1, 2016

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

born2net commented Jul 1, 2016

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

@rozzzly

This comment has been minimized.

Show comment
Hide comment
@rozzzly

rozzzly 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.

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

This comment has been minimized.

Show comment
Hide comment
@kitsonk

kitsonk Jul 4, 2016

Contributor

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).

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

This comment has been minimized.

Show comment
Hide comment
@DethAriel

DethAriel 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.

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

This comment has been minimized.

Show comment
Hide comment
@aluanhaddad

aluanhaddad Oct 21, 2016

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.

Contributor

aluanhaddad commented Oct 21, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@DethAriel

DethAriel Oct 21, 2016

@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

@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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Oct 21, 2016

Contributor

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;
  }
}
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

This comment has been minimized.

Show comment
Hide comment
@DethAriel

DethAriel Oct 21, 2016

Thx, @mhegazy , that worked indeed

Thx, @mhegazy , that worked indeed

@sunny-g

This comment has been minimized.

Show comment
Hide comment
@sunny-g

sunny-g 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)

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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Nov 1, 2016

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@zeeshanjan82

zeeshanjan82 Nov 3, 2016

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.

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

This comment has been minimized.

Show comment
Hide comment
@108adams

108adams 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...

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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Nov 3, 2016

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@aluanhaddad

aluanhaddad Nov 3, 2016

Contributor

@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 '*';
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

This comment has been minimized.

Show comment
Hide comment
@adamreisnz

adamreisnz Nov 30, 2016

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.

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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Nov 30, 2016

Contributor

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.

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.

@adamreisnz

This comment has been minimized.

Show comment
Hide comment
@adamreisnz

adamreisnz Nov 30, 2016

I lack both the time and desire to maintain my own typings definitions for 3rd party libraries ;)

adamreisnz commented Nov 30, 2016

I lack both the time and desire to maintain my own typings definitions for 3rd party libraries ;)

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Nov 30, 2016

Contributor

I lack both the time and desire to maintain my own typings definitions for 3rd party libraries ;)

And that is perfectly fine. just use declare module "moment"; which is the equivalent of declare var $: any for modules, and the compiler will not bother you about it again.

Contributor

mhegazy commented Nov 30, 2016

I lack both the time and desire to maintain my own typings definitions for 3rd party libraries ;)

And that is perfectly fine. just use declare module "moment"; which is the equivalent of declare var $: any for modules, and the compiler will not bother you about it again.

@aluanhaddad

This comment has been minimized.

Show comment
Hide comment
@aluanhaddad

aluanhaddad Nov 30, 2016

Contributor

@mhegazy's suggestion is a very good one. It will take you about 20 seconds to do that. By the way, with respect to moment, they forgot a couple of units that I was using and they were very open to accepting my pull request.

Contributor

aluanhaddad commented Nov 30, 2016

@mhegazy's suggestion is a very good one. It will take you about 20 seconds to do that. By the way, with respect to moment, they forgot a couple of units that I was using and they were very open to accepting my pull request.

@yortus

This comment has been minimized.

Show comment
Hide comment
@yortus

yortus Nov 30, 2016

Contributor

The downside to adding declare module "moment"; is that you will no longer have any IDE intellisense or static type checking for any moment-related code. And the anys that arise tend to bleed out into surrounding code, shutting down many static checks there as well. It's a heavy price to pay for suppressing errors related to a single problematic enum value.

Contributor

yortus commented Nov 30, 2016

The downside to adding declare module "moment"; is that you will no longer have any IDE intellisense or static type checking for any moment-related code. And the anys that arise tend to bleed out into surrounding code, shutting down many static checks there as well. It's a heavy price to pay for suppressing errors related to a single problematic enum value.

@adamreisnz

This comment has been minimized.

Show comment
Hide comment
@adamreisnz

adamreisnz Nov 30, 2016

@aluanhaddad there was a pull request open to fix the issue, but it got closed in favour of another one, which introduced breaking changes (and still didn't add support for isoWeek), so not sure what happened there.

The point is that these issues are bound to arise more frequently in the future with the adoption of Angular 2 etc. so a way to supress particular errors would be useful I can imagine.

adamreisnz commented Nov 30, 2016

@aluanhaddad there was a pull request open to fix the issue, but it got closed in favour of another one, which introduced breaking changes (and still didn't add support for isoWeek), so not sure what happened there.

The point is that these issues are bound to arise more frequently in the future with the adoption of Angular 2 etc. so a way to supress particular errors would be useful I can imagine.

@juanmirod

This comment has been minimized.

Show comment
Hide comment
@juanmirod

juanmirod Dec 13, 2016

I have this issue with a node core library (net, node 6.9 LTS):

server = net.createServer({ pauseOnConnect: true }, function(connection) { ... }) 
// [ts] severity: 'Error'
message: 'Argument of type '{ pauseOnConnect: boolean; }' is not assignable to parameter of type '{ allowHalfOpen?: boolean; }'.
  Object literal may only specify known properties, and 'pauseOnConnect' does not exist in type '{ allowHalfOpen?: boolean; }'.'

And also with ioredis library:

var redis = new Redis(CONFIG.redis); 
// [ts] severity: 'Error'
message: 'Only a void function can be called with the 'new' keyword.'

As @yortus and @adamreisnz pointed, this is a common problem as definition files are not always correctly updated. Besides, If you have to sacrifice TS benefits using declare module "x"; why would you use TS in the first place?

juanmirod commented Dec 13, 2016

I have this issue with a node core library (net, node 6.9 LTS):

server = net.createServer({ pauseOnConnect: true }, function(connection) { ... }) 
// [ts] severity: 'Error'
message: 'Argument of type '{ pauseOnConnect: boolean; }' is not assignable to parameter of type '{ allowHalfOpen?: boolean; }'.
  Object literal may only specify known properties, and 'pauseOnConnect' does not exist in type '{ allowHalfOpen?: boolean; }'.'

And also with ioredis library:

var redis = new Redis(CONFIG.redis); 
// [ts] severity: 'Error'
message: 'Only a void function can be called with the 'new' keyword.'

As @yortus and @adamreisnz pointed, this is a common problem as definition files are not always correctly updated. Besides, If you have to sacrifice TS benefits using declare module "x"; why would you use TS in the first place?

@aluanhaddad

This comment has been minimized.

Show comment
Hide comment
@aluanhaddad

aluanhaddad Dec 16, 2016

Contributor

You can also augment the module with the types that are missing so as to not lose intellisence.

Contributor

aluanhaddad commented Dec 16, 2016

You can also augment the module with the types that are missing so as to not lose intellisence.

@gdh1995

This comment has been minimized.

Show comment
Hide comment
@gdh1995

gdh1995 Dec 29, 2016

Contributor

Well, when I write:

if (typeof Symbol === "function" && Symbol.match) {
  // ...
}

The typescript compiler always reports an error Cannot find name 'Symbol' if target is es5, although this code indeed works well just as I expected.

So I agree that we badly need some control directives working in comment lines.

Contributor

gdh1995 commented Dec 29, 2016

Well, when I write:

if (typeof Symbol === "function" && Symbol.match) {
  // ...
}

The typescript compiler always reports an error Cannot find name 'Symbol' if target is es5, although this code indeed works well just as I expected.

So I agree that we badly need some control directives working in comment lines.

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Dec 29, 2016

Contributor
declare var Symbol: any;
Contributor

mhegazy commented Dec 29, 2016

declare var Symbol: any;
@DanielRosenwasser

This comment has been minimized.

Show comment
Hide comment
@DanielRosenwasser

DanielRosenwasser Dec 30, 2016

Member

@gdh1995 @mhegazy Or just use the real fix which is setting the lib flag to es2015.

Member

DanielRosenwasser commented Dec 30, 2016

@gdh1995 @mhegazy Or just use the real fix which is setting the lib flag to es2015.

@uglow

This comment has been minimized.

Show comment
Hide comment
@uglow

uglow Jul 26, 2017

I'm using 2.3.3. I'll give 2.4.1 a try. Thank you 😊

uglow commented Jul 26, 2017

I'm using 2.3.3. I'll give 2.4.1 a try. Thank you 😊

@FabianTe

This comment has been minimized.

Show comment
Hide comment
@FabianTe

FabianTe Aug 2, 2017

This should be included. I am working with a custom js engine which allows a single .js file to return a value. See my gist for an example. I use TS to generate my .js files and of course TS does not know about that and throws:

A 'return' statement can only be used within a function body.

FabianTe commented Aug 2, 2017

This should be included. I am working with a custom js engine which allows a single .js file to return a value. See my gist for an example. I use TS to generate my .js files and of course TS does not know about that and throws:

A 'return' statement can only be used within a function body.
@unional

This comment has been minimized.

Show comment
Hide comment
Contributor

unional commented Aug 5, 2017

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats Aug 7, 2017

@mhegazy I've hit this kind of problem in a number of different ways.

My current situation (the entire flow assumes declaration mode):

  • class decorators require a class declaration (not class expression) and I'm inside a function - in principle this could be fixed, but it's not today.
  • ok, no problem I'll make the expression a declaration
  • no dice, the declaration now has an unused name
  • ok, no problem I'll return it
  • no dice, Return type of public method from exported class has or is using private name
  • ... ?

Basically, the root cause here is that expressions can't be decorated, but it's unreasonable for you to drop everything to implement that functionality. In the meantime, it's sensible for me to simply suppress this error. I'd be fine if suppressing an error required me to find the associated TypeScript issue and say something like // TS-LIMITATION:#9448 although I suspect that would result in a huge amount of new pointless issues from your perspective.

I'd even be fine if you added specific targeted suppressions for known issues that you aren't ready to take up yet, but only if that was done quickly and without too much design effort (that would make the mechanism pointless 😉 )

wycats commented Aug 7, 2017

@mhegazy I've hit this kind of problem in a number of different ways.

My current situation (the entire flow assumes declaration mode):

  • class decorators require a class declaration (not class expression) and I'm inside a function - in principle this could be fixed, but it's not today.
  • ok, no problem I'll make the expression a declaration
  • no dice, the declaration now has an unused name
  • ok, no problem I'll return it
  • no dice, Return type of public method from exported class has or is using private name
  • ... ?

Basically, the root cause here is that expressions can't be decorated, but it's unreasonable for you to drop everything to implement that functionality. In the meantime, it's sensible for me to simply suppress this error. I'd be fine if suppressing an error required me to find the associated TypeScript issue and say something like // TS-LIMITATION:#9448 although I suspect that would result in a huge amount of new pointless issues from your perspective.

I'd even be fine if you added specific targeted suppressions for known issues that you aren't ready to take up yet, but only if that was done quickly and without too much design effort (that would make the mechanism pointless 😉 )

@polyglotinc

This comment has been minimized.

Show comment
Hide comment
@polyglotinc

polyglotinc Aug 7, 2017

I dont want to get unreachable code error (where I am happy to annotate "shut up on unreachable code error right here") when I do something like
if (false){ ...complicated debug code that I dont want to delete/forget... }

I dont want to get unreachable code error (where I am happy to annotate "shut up on unreachable code error right here") when I do something like
if (false){ ...complicated debug code that I dont want to delete/forget... }

@mnn

This comment has been minimized.

Show comment
Hide comment
@mnn

mnn Aug 8, 2017

So, TypeScript compiler is still missing an option to "shut up and not mess up other tools". It would be really useful for us to have this option via comments and via compiler switches for specific files or even glob. We are stuck at using old version of tools because we don't want to lose auto-reload (newer versions doesn't auto-reload when errors are present). So we either turn off buggy option noImplicitAny (which I really don't want to, I am using TypeScript because of typechecking and with allowed implicit any TypeScript doesn't bring that much to a table) or stay on ancient versions of packages. Yes, I reported the bug in both, WebPack and AwesomeTypeScript loader, but nobody cares. The issue is being ignored for many months now. I see it is exactly the same with TypeScript package :-(.

mnn commented Aug 8, 2017

So, TypeScript compiler is still missing an option to "shut up and not mess up other tools". It would be really useful for us to have this option via comments and via compiler switches for specific files or even glob. We are stuck at using old version of tools because we don't want to lose auto-reload (newer versions doesn't auto-reload when errors are present). So we either turn off buggy option noImplicitAny (which I really don't want to, I am using TypeScript because of typechecking and with allowed implicit any TypeScript doesn't bring that much to a table) or stay on ancient versions of packages. Yes, I reported the bug in both, WebPack and AwesomeTypeScript loader, but nobody cares. The issue is being ignored for many months now. I see it is exactly the same with TypeScript package :-(.

@RyanCavanaugh

This comment has been minimized.

Show comment
Hide comment
@RyanCavanaugh

RyanCavanaugh Aug 8, 2017

Member

@polyglotinc if (!!false) {

Member

RyanCavanaugh commented Aug 8, 2017

@polyglotinc if (!!false) {

@polyglotinc

This comment has been minimized.

Show comment
Hide comment
@polyglotinc

polyglotinc Aug 9, 2017

@RyanCavanaugh Well, for that matter, (!true)works ... I didnt even think of those as possibilities because I (as an ex-compiler-writer) gave the compiler more credit with regard to constant/literal expression collapsing... I guess I figured if it was going to be a busy-body about if (false), it would know if (!true) was the same thing!

polyglotinc commented Aug 9, 2017

@RyanCavanaugh Well, for that matter, (!true)works ... I didnt even think of those as possibilities because I (as an ex-compiler-writer) gave the compiler more credit with regard to constant/literal expression collapsing... I guess I figured if it was going to be a busy-body about if (false), it would know if (!true) was the same thing!

@jmlopez-rod

This comment has been minimized.

Show comment
Hide comment
@jmlopez-rod

jmlopez-rod Aug 9, 2017

@unional the SO question could be written a bit clearer and perhaps that is why we need the compiler to tell us about possible errors. See this screenshot showing the error the user wants to suppress

screen shot 2017-08-09 at 12 43 20 am

Notice that in the screenshot I only have one error. That is because I already fixed one problem caught by the compiler.

private keyHandlers = {
    'ArrowDown': function ($event: any) {
      this.handleArrowDown($event);
    },
    'ArrowUp': ($event: any) => {
      this.handleArrowUp($event);
    },
  };

The user claims that the handleArrow* are being used but typescript doesn't see it being used. As far as typescript is concerned the this in this.handleArrowDown($event); could be any object that has the method handleArrowDown. With the arrow function it now knows that this is the instance of the class and thus it sees handleArrowUp being used.

Another option: Use the fake first parameter this.

  private keyHandlers = {
    'ArrowDown': function (this: SomeComponent, $event: any) {
      this.handleArrowDown($event);
    },
    'ArrowUp': ($event: any) => {
      this.handleArrowUp($event);
    },
  };

@unional the SO question could be written a bit clearer and perhaps that is why we need the compiler to tell us about possible errors. See this screenshot showing the error the user wants to suppress

screen shot 2017-08-09 at 12 43 20 am

Notice that in the screenshot I only have one error. That is because I already fixed one problem caught by the compiler.

private keyHandlers = {
    'ArrowDown': function ($event: any) {
      this.handleArrowDown($event);
    },
    'ArrowUp': ($event: any) => {
      this.handleArrowUp($event);
    },
  };

The user claims that the handleArrow* are being used but typescript doesn't see it being used. As far as typescript is concerned the this in this.handleArrowDown($event); could be any object that has the method handleArrowDown. With the arrow function it now knows that this is the instance of the class and thus it sees handleArrowUp being used.

Another option: Use the fake first parameter this.

  private keyHandlers = {
    'ArrowDown': function (this: SomeComponent, $event: any) {
      this.handleArrowDown($event);
    },
    'ArrowUp': ($event: any) => {
      this.handleArrowUp($event);
    },
  };
@unional

This comment has been minimized.

Show comment
Hide comment
@unional

unional Aug 9, 2017

Contributor

@jmlopez-rod Thanks. These are good alternative. I especially like function(this: SomeComponent, ...) {...} solution because that is the most flexible.

Arrow function doesn't work if the keyHandlers is not a part of the class:

const keyHandlers = {
  'ArrowDown': function (this: SomeComponent, $event) {
    this.handleArrowDown($event); // error on accessing private method, filing an issue for it.
  },

  'ArrowUp': ($event) => { // doesn't work, duh
    this.handleArrowUp($event);
  }
}

export class SomeComponent {
  onKeyDown($event) {
    if (typeof keyHandlers[$event.code] === 'function') {
      keyHandlers[$event.code]($event);
    }
  }
  private handleArrowDown(_event) {
    // ...
  }

  private handleArrowUp(_event) {
    // ...
  }
}

On the other hand, arrow function is the most straight forward in this context.

Contributor

unional commented Aug 9, 2017

@jmlopez-rod Thanks. These are good alternative. I especially like function(this: SomeComponent, ...) {...} solution because that is the most flexible.

Arrow function doesn't work if the keyHandlers is not a part of the class:

const keyHandlers = {
  'ArrowDown': function (this: SomeComponent, $event) {
    this.handleArrowDown($event); // error on accessing private method, filing an issue for it.
  },

  'ArrowUp': ($event) => { // doesn't work, duh
    this.handleArrowUp($event);
  }
}

export class SomeComponent {
  onKeyDown($event) {
    if (typeof keyHandlers[$event.code] === 'function') {
      keyHandlers[$event.code]($event);
    }
  }
  private handleArrowDown(_event) {
    // ...
  }

  private handleArrowUp(_event) {
    // ...
  }
}

On the other hand, arrow function is the most straight forward in this context.

@amiraliakbari

This comment has been minimized.

Show comment
Hide comment
@amiraliakbari

amiraliakbari Aug 22, 2017

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?

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

This comment has been minimized.

Show comment
Hide comment
@fabiandev

fabiandev Aug 22, 2017

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

(window as any).console = {};

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

(window as any).console = {};
@b264

This comment has been minimized.

Show comment
Hide comment
@b264

b264 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

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

@andy-ms

This comment has been minimized.

Show comment
Hide comment
@andy-ms

andy-ms Oct 12, 2017

Contributor

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

Contributor

andy-ms commented Oct 12, 2017

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

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Oct 12, 2017

Contributor

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.

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.

@andy-ms

This comment has been minimized.

Show comment
Hide comment
@andy-ms

andy-ms Oct 12, 2017

Contributor

Created #19139.

Contributor

andy-ms commented Oct 12, 2017

Created #19139.

@Lonli-Lokli

This comment has been minimized.

Show comment
Hide comment
@Lonli-Lokli

Lonli-Lokli Oct 17, 2017

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

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

@andy-ms

This comment has been minimized.

Show comment
Hide comment
@andy-ms

andy-ms Oct 17, 2017

Contributor

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.

Contributor

andy-ms 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

This comment has been minimized.

Show comment
Hide comment
@webia1

webia1 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?

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?

@andy-ms

This comment has been minimized.

Show comment
Hide comment
@andy-ms

andy-ms Jan 10, 2018

Contributor

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

Contributor

andy-ms commented Jan 10, 2018

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

@miltonbecker

This comment has been minimized.

Show comment
Hide comment
@miltonbecker

miltonbecker 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!

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

This comment has been minimized.

Show comment
Hide comment
@RyanCavanaugh

RyanCavanaugh Mar 20, 2018

Member

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

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

Member

RyanCavanaugh commented Mar 20, 2018

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

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

@miltonbecker

This comment has been minimized.

Show comment
Hide comment
@miltonbecker

miltonbecker Mar 20, 2018

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

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

@tomshaw

This comment has been minimized.

Show comment
Hide comment
@tomshaw

tomshaw 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 */

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 join this conversation on GitHub. Already have an account? Sign in to comment