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

Linter objects to "any" even in type guards #628

Closed
lcrocker opened this issue Feb 28, 2021 · 4 comments
Closed

Linter objects to "any" even in type guards #628

lcrocker opened this issue Feb 28, 2021 · 4 comments

Comments

@lcrocker
Copy link

lcrocker commented Feb 28, 2021

The linter (correctly, in general) objects to any use of "any", but there's one place where TypeScript all but requires it, which is user-defined type guards. For example:

function isMyType(obj: any) obj is MyType {
    if (! obj) return false;
    if (! (obj instanceof Object)) return false;
    if (! ('number' === typeof obj.count)) return false;
    return true;
}

One might argue that this is an issue with TypeScript in that it doesn't allow the use of "unknown" here without throwing errors and doesn't have any other way to check for the existence and type of properties of an unknown. But until this is fixed in TypeScript, it would be handy if the linter made an exception for type guards.

@Soremwar
Copy link

Soremwar commented Feb 28, 2021

You can absolutely use unknown here, in fact I'd say this is a perfect use case for unknown, since it will force you to assert the type and properties of the unknown value before accessing them, handling any possible runtime error

As for the use of any, your code as it is totally a thing you can do in Deno, but we have to make a distinction between implicit and explicit any

In the case of implicit any, TypeScript can't guess the type of a variable and in Deno settings this is listed as an error that won't allow you to run your code.

function x(y){} // TypeScript can't guess what "y" should be, throws an error

Explicit any on the other hand will allow you to run your code, but will be displayed as a warning when using the linter.

function x(y: any){} // Totally valid and runnable code, it will generate a warning for "any"

So this isn't so much about the behavior of any or unknown, but the lack of understanding of how they should be used

@kitsonk kitsonk transferred this issue from denoland/deno Mar 1, 2021
@kitsonk
Copy link
Contributor

kitsonk commented Mar 1, 2021

Correct, unknown should be used in user-defined type guards.

@kitsonk kitsonk closed this as completed Mar 1, 2021
@lcrocker
Copy link
Author

lcrocker commented Mar 2, 2021

Using "unknown" in user-defined type guards is the right thing to do, but it doesn't work, at least in the current state of TypeScript because there's no way to assert the presence of a property.
See, e.g., microsoft/TypeScript#25720 , microsoft/TypeScript#21732 . We should say explicitly that we won't fix this because we expect TypeScript to fix their end.

@Soremwar
Copy link

Soremwar commented Mar 2, 2021

@lcrocker

there's no way to assert the presence of a property

Read the docs man

This is a safe way of asserting a value using unknown, it won't trigger getters or return false on validation over falsy values

function checkProperty(value: unknown){
  if(typeof value === "object" && value !== null){
    return "my_property" in value;
  }
  return false;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants