Open trusktr opened 4 years ago
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.
Seems like a lot of opportunity here for Hegel to prevent a lot of errors that TS doesn't!
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 😥.
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 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
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.
To allow for type refinement to be abstracted into functions:
Try