Closed rrichardson closed 2 years ago
Cool idea. Where were you two weeks ago!
I think the issue here (I'm not at an IDE to check) is that the T type should be the contained type of the Result. The outer Ok has T = Ok<number>
and your definition asks that this
be Result<Result<T,_>>
which it never can be.
You will need to infer the type of the contained T, perhaps something like:
flatten(this: Result<T, E>): T extends Result<infer U, E> ? Result<U, E> : null {}
The null
here indicates the instance where it's not a nested result, up to you how you want to handle that. I haven't tested this, but maybe it works for what you want?
Figured it out.. it just needed a new set of type params for the flatten method itself, as T and E don't equal Result<T, E>
https://github.com/traverse1984/oxide.ts/pull/6
I think the other approach, which is more closely related to your example, is :
flatten<T, U extends Result<T, E>>(this: Result<U, E>): Result<T, E> {
return this.andThen(x => x)
}
I'm not sure which one is better. I went with the flatten<T, E> cause it's simple.
My hope is to copy these methods from Rust: (https://doc.rust-lang.org/src/core/result.rs.html#1704)
I attempted to implement these, but alas, Typescripts type system is beyond my reckoning. My first approach was a naive one, my expectation was that this would work, though the type error would not be ergonomic if
flatten()
was called on a non-nested result.When trying to test flatten, I get the unergonomic error message that I expected, but not for the reason I expected. I guess Ok doesn't implicitly convert to Result..
results in