Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving option.getOrElse type inference #1917

Open
vinassefranche opened this issue Dec 7, 2023 · 1 comment
Open

Improving option.getOrElse type inference #1917

vinassefranche opened this issue Dec 7, 2023 · 1 comment

Comments

@vinassefranche
Copy link
Contributor

🚀 Feature request

Current Behavior

Today, when using option.getOrElse, the type of what's inside the option is inferred from the first argument (the or else argument). This leads to typescript easily erroring when returning an array or an option.none (non exhaustive list):

declare const foo: Option<ReadonlyArray<string>>
pipe(
  foo,
  option.getOrElse(() => []),
)
// ts error: Argument of type 'Option<readonly string[]>' is not assignable to parameter of type 'Option<never[]>'.

To fix this, I can use getOrElseW but the resulting type will be not that great (readonly string[] | never[]) or enforce the type like this:

pipe(
  foo,
  option.getOrElse<ReadonlyArray<string>>(() => []),
)
// -> no error when getOrElse is typed

Desired Behavior

It would be great that the inference would be done from the option that is passed to getOrElse instead so that this would be valid code:

declare const foo: Option<ReadonlyArray<string>>
pipe(
  foo,
  option.getOrElse(() => []),
)

Suggested Solution

Use NoInfer from ts-toolbelt. Here's the implementation if we don't want to add a new dependency:

type NoInfer<A extends any> =
    [A][A extends any ? 0 : never]

and use it like this:

export declare const getOrElse: <A>(onNone: LazyArg<NoInfer<A>>) => (ma: Option<A>) => A

Who does this impact? Who is this for?

This can impact any user and would help greatly new users that don't understand why typescript is not happy.

Describe alternatives you've considered

None

Additional context

Your environment

Software Version(s)
fp-ts 2.16.1
TypeScript 5.3.3
@asjir
Copy link

asjir commented Mar 15, 2024

thank you for the issue I'm already using your proposed implementation with the intrinsic ts NoInfer implementation
I've noticed though that this causes the application without piping, i.e.:
const x = getOrElse(() => 3)(O.some(3)) to infer x as unknown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants