Repository navigation
Divide by zero Typechecking #21955
Description
Activity
DanielRosenwasser commented
on Feb 15, 2018 MemberMore actionsJust to weigh in: given that
numberalready implicitly includes0, it seems- Kind of weird to say that
number | 0would be meaningfully different from0. - Like kind of a weird responsibility to place on the user to remember to say "hey this
numbercould be zero" when so could every othernumber.
- Kind of weird to say that
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptIn DiscussionNot yet reached consensusNot yet reached consensus
on Feb 15, 2018 RyanCavanaugh commented
on Feb 15, 2018 MemberMore actionsSince this produces
Infinity(which is meaningful) instead ofNaNit's hard to even interpret it as an error.
intersectDistance(ray1, ray2)returnsInfinitywhen they're parallel... not a problem?Reacted by Aluan Haddad and Max HeiberKiaraGrouwstra commented
on Feb 15, 2018 ContributorMore actionsAs Daniel said, this only make sense for numbers known at compile time.
With return types,T extends 0 ? Infinity : numbercould make sense.Idris, famous for dependent types like this, uses
safe_div : (x : Int) -> (y : Int) -> {auto p : so (y /= 0)} -> Int.Given an equivalent to Flow's
$Call(I'm gonna use regular function syntax for this), I'd imagine a TS equivalent to be implemented likedeclare function div<B extends number, NotZero = { (v: '1') => 'whatever'; }(B extends 0 ? '0' : '1')>(a: number, b: B).To break that down, I'm catching the literal type of the denominator in a generic (
B), checking whether it is0, then plugging the answer to that into a partial function. When it turns out the answer does not match what we wanted, the requirements of the partial function are not satisfied, yielding a type error.(I experimented with this idea in my PR for that feature (#17961), although my implementation ended up too glitchy, relying on synthetic type nodes that resulted in error tooltips showing up in the wrong place.)
Wouldn't something like this work if Infinity was a type?
declare function div(x: number, y: 0): Infinity declare function div(x: number, y: number): number
KiaraGrouwstra commented
on Feb 17, 2018 ContributorMore actionsyes it would. :)
Interesting. It appears nothing actually breaks until something needs and actual number. It would be cool if
InfinityandNaNcould be considered separate types.You can actually kinda already define an
Infinitynumeric literal type. Just make a type alias to a number that's too big for JS to accurately represent and it'll round toInfinity. The issue is that the globalInfinityconstant isn't of this type 😉 , and declaration emit for this type may not work 😮 . It's super hacky. We should really just add theNaNandInfinitynumeric literal types (back). 🐱 Plus,NaNeven has wonky comparability we should encode 😄Reacted by AnyhowStep and Matthew RadcliffeKiaraGrouwstra commented
on Feb 22, 2018 ContributorMore actionson second thought, I fear my partial function idea might well blow up as soon as it realizes you're potentially plugging in more than it could handle. hm.
KiaraGrouwstra commented
on Mar 18, 2018 ContributorMore actionsit seems Joe Calzaretta (@jcalz) pulled off something like this at #21316 (comment) to disallow certain input
I'd really love to see
InfinityandNaNtypes in TS.
It's always bothered me how they're just... Missing.And adding a special case for the following doesn't seem too bad,
declare const x : any; if (x === NaN) { //x is now of type `never` }
Reacted by Matthew RadcliffeAnyhowStep reminder that there are many NaNs in IEEE 754 floats, and JS adds its own layer of bizarreness on top:
js> var a = 0/0; NaN js> var b = {} - 1; NaN js> a == b; false js> a === b; false js> isNaN(a); true js> isNaN(b); true js> NaN == NaN; false
It raises the potential question of whether to lump them together.
Could we define
real, a subset ofnumberwhich excludesInfinityornan?Then the type of division between two
realvalues would benumber, but addition / subtraction / multiplication would still bereal.By your definition,
1e308is areal.But their multiplication,
1e308*1e308 > InfinityAnd their addition,
1e308+1e308 > InfinityAnd subtraction,
-1e308-1e308 > -InfinityOh yeah, we've only got floats :(
We have type literals for numbers already and a
strictNullCheckcompiler option -- wouldn't it be awesome if we had a type guard again divide-by-zero errors? I'm building a game that involved a lot of math, computing intersections of lines and such. But what if a line is parallel? It would be cool if the compiler would suggest this as a type error.TypeScript Version: 2.7.0-dev.201xxxxx