Closed rbalicki2 closed 3 weeks ago
This is already solved in Promise.allSettled
Is throw null a common pattern? Not directly. 6.1k results on GitHub.
throw new Error
3.3Mthrow err
1.8Mthrow error
946k That's less than 0.1% and almost all 6.1k results comes from big libraries like nextjs
, which uses throw null
for different reasons.
[T, null] | [null, E]
is the wrong type. As you can see with tuple-it. The correct type should be [E] | [null, T]
@arthurfiorette
The type [E] | [null, T]
is also incorrect: TS Playground, the type parameter E
makes the discriminating this type impossible.
The correct type is [{}] | [null, T]
: TS Playground
.length === 1
? If so, that should be indicated in the docs. And that also means that we cannot destructure on the same line. (Maybe one can destructure as { '0': Error, '1': Value, 'length': isError }
, though)E
extends {}
(aka is not null), that type will infect every other library. Consider https://github.com/Effect-TS/effect/blob/main/packages/effect/src/Effect.ts#L95, E
does not extend {}
. In order to be compatible with this new syntax, effect will have to enforce that E
extends {}
throughout.Anyway, @DScheglov is right about the inability to discriminate in a generic context with that type.
This makes it impossible to refine the type in a generic function
T
andE
can containnull
, it is impossible to determine whether the result is in the "error" or "ok" case. There are no such problems with a discriminated union.[T, null] | [null, E]
, which is backwards. I won't fix that, because that's indicative of the fact that ordering is a footgun here, which is solved by using a discriminated union.T
andE
, which is to say, pretty much every single API.Result<T, Exclude<E, null>>
, but I couldn't get it to work. But let's assume that something like this does work! That means that this constraint will propagate itself everywhere.One response: you should never throw null.
throw null
a common pattern? Not directly. 6.1k results on GitHub. This is likely to be much more common than this indicates, however, due to code that accidentally throws null, such asthrow lookUpUserReadableErrorMessage(e)
.throw null
a bad pattern? Not necessarily. If your error case contains no information, it only hurts performance to allocate objects, though one could conceivablythrow true
or something.But a discriminated union also allocates an object
Conclusion