Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

the "is" keyword (type predicates) #227

Open
trusktr opened this issue May 20, 2020 · 6 comments
Open

the "is" keyword (type predicates) #227

trusktr opened this issue May 20, 2020 · 6 comments
Labels
enhancement New feature or request

Comments

@trusktr
Copy link

trusktr commented May 20, 2020

To allow for type refinement to be abstracted into functions:

function isNumber(n: unknown): n is number {
  if (typeof n === 'number' && !isNaN(n)) return true
  return false
}

Try

@trusktr
Copy link
Author

trusktr commented May 20, 2020

Perhaps the following would have a type error:

function isNumber(n: unknown): n is number {
  if (typeof n === 'number') return true // Error, function returns true if n is `number | NaN`
  return false
}

because the type system can treat NaN as not a number (hehe), and throw an error to prevent (possibly silent) runtime errors from NaN being passed around.

@trusktr
Copy link
Author

trusktr commented May 20, 2020

Seems like a lot of opportunity here for Hegel to prevent a lot of errors that TS doesn't!

@peter-leonov
Copy link

That would be super sweet to make NaN a separate type and exclude it from number, but making it strictly true requires checking results of all the arithmetical operations 😥.

@JSMonk
Copy link
Owner

JSMonk commented May 20, 2020

Seems like a lot of opportunity here for Hegel to prevent a lot of errors that TS doesn't!

We want to make it implicity. You can't set directly which type you want to refine.
So, your example will look like this:

function isNumber(n: unknown) {
  return typeof n === 'number' && !isNaN(n)
}
const a: number | boolean = 2;
if (isNumber(a)) {
 // a will be number
}

But the feature currently in development. So, I will note this issue in commits related to the feature.

@JSMonk JSMonk added the enhancement New feature or request label May 20, 2020
@thecotne
Copy link
Contributor

thecotne commented May 21, 2020

@JSMonk you should allow developer to specify what he/she wants to refine to so refinement itself can be checked against expectation of a developer

for example

function isNumber<T>(n: T): $Refine<T, number>  {
  return typeof n === 'string'// error
}

function isString<T>(n: T): $Refine<T, string> {
  return typeof n === 'string'// ok
}

declare class Array {
  static isArray<T>(T): $Refine<T, Array>
}

of course inference of $Refine would be super cool but developer needs to be able to specify intent

@trusktr
Copy link
Author

trusktr commented May 22, 2020

That's a good point. It could be possible to make a mistake in the return statement, and therefore by accident change the type guard that the boolean represents.

@trusktr trusktr changed the title the "is" keyword the "is" keyword (type predicates) May 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants