Within my Typescript project, I've implemented a Result type to be returned from functions, containing either an error or some data. This can take the form of [Error, null]
, or [null, Data]
. Here's an example:
type Result<Data> = [ Error | null, Data | null ]
function randomSuccess(): Result<string> {
if ( Math.random() > 0.5 ) {
return [ null, 'success' ]
else {
return [ new Error( 'oh no' ), null ]
}
}
const [ err, result ] = randomSuccess()
if ( err ) {
.... // now able to handle the extracted error and result
I aim for Typescript to validate that only one of Error or Data is ever not null. For instance:
...
return [ new Error( 'oh no' ), 'success' ]
should trigger an error.
My initial strategy to define a type using conditional types was as follows:
type Result<Data> = null extends Error ? [ null, Data ] : [ Error, null ]
This configuration compiles successfully when the function returns an error. However, when returning valid data - like return [ null, 'success' ]
- the compiler raises an issue:
Type 'null' is not assignable to type 'Error'
While I comprehend the compiler error to some extent, it seems like Error
lacks a parameter in my type definition, causing null extends Error
to always be false. Yet, finding the next steps proves challenging for me.
How do I devise a type that ensures validity is maintained within either [Error, null]
or [null, Data]
, while never allowing [Error, Data]
?