I know how to keep result value type when inject other deal in orElse().
mitsuru793 opened this issue · 1 comments
mitsuru793 commented
Thank you for maintaining this library.
I know how to keep result value type when inject other deal.
Don't orElse()
return other type error?
const writeCache = (cacheFilePath: string, content: string): Result<void, Error> => {
fs.writeFileSync(cacheFilePath, content)
return ok(undefined)
}
const requestByApi = async (): Promise<string> => {
console.log('calling api...')
return Promise.resolve('new content')
}
const safeRequestByApi = (): ResultAsync<string, unknown> => {
return ResultAsync.fromPromise(requestByApi(), (e) => e)
}
okAsync(undefined)
.orElse(_ => { // Compile Error
return safeRequestByApi()
.andThen(res => {
const mayWrote = writeCache('cachePath', res) // I want to tap only.
if (mayWrote.isOk()) {
return ok(res) // I want not change return keeping the returned of safeRequestByApi().
}
return err(mayWrote.error)
})
})
Got TypeScript Error
No overload matches this call.
Overload 1 of 3, '(f: (e: never) => Result<undefined, unknown>): ResultAsync<undefined, unknown>', gave the following error.
Argument of type '(_: never) => ResultAsync<string, unknown>' is not assignable to parameter of type '(e: never) => Result<undefined, unknown>'.
Type 'ResultAsync<string, unknown>' is not assignable to type 'Result<undefined, unknown>'.
Type 'ResultAsync<string, unknown>' is missing the following properties from type 'Err<undefined, unknown>': error, isOk, isErr, asyncAndThen, and 3 more.
Overload 2 of 3, '(f: (e: never) => ResultAsync<undefined, unknown>): ResultAsync<undefined, unknown>', gave the following error.
Argument of type '(_: never) => ResultAsync<string, unknown>' is not assignable to parameter of type '(e: never) => ResultAsync<undefined, unknown>'.
Type 'ResultAsync<string, unknown>' is not assignable to type 'ResultAsync<undefined, unknown>'.
Type 'string' is not assignable to type 'undefined'.
Overload 3 of 3, '(f: (e: never) => Result<undefined, unknown> | ResultAsync<undefined, unknown>): ResultAsync<undefined, unknown>', gave the following error.
Argument of type '(_: never) => ResultAsync<string, unknown>' is not assignable to parameter of type '(e: never) => Result<undefined, unknown> | ResultAsync<undefined, unknown>'.
Type 'ResultAsync<string, unknown>' is not assignable to type 'Result<undefined, unknown> | ResultAsync<undefined, unknown>'.
Type 'ResultAsync<string, unknown>' is not assignable to type 'ResultAsync<undefined, unknown>'.ts(2769)
supermacro commented
when inject other deal.
I'm not sure what you mean by this.
In any case, I am able to reproduce your type error. But this stems from a mismatch of types and not some bug in neverthrow.
Looking at the type signature of orElse
class Result<T, E> { // <--- INPUT
orElse<A>(
callback: (error: E) => Result<T, A>
): Result<T, A> { ... } // <-- OUTPUT
}
We can see that the input result has a "success" type of T
and the output result has a success type of T
. In other words; the success type does not change.
You can fix this by changing the code to the following:
const writeCache = (cacheFilePath: string, content: string): Result<void, Error> => {
fs.writeFileSync(cacheFilePath, content)
return ok(undefined)
}
const requestByApi = async (): Promise<string> => {
console.log('calling api...')
return Promise.resolve('new content')
}
const safeRequestByApi = (): ResultAsync<string, unknown> => {
return ResultAsync.fromPromise(requestByApi(), (e) => e)
}
+ okAsync<string, unknown>('now its a string')
- okAsync(undefined)
.orElse(_ => { // Compile Error
return safeRequestByApi()
.andThen(res => {
const mayWrote = writeCache('cachePath', res) // I want to tap only.
if (mayWrote.isOk()) {
return ok(res) // I want not change return keeping the returned of safeRequestByApi().
}
return err(mayWrote.error)
})
})