mobily / ts-belt

🔧 Fast, modern, and practical utility library for FP in TypeScript.
https://mobily.github.io/ts-belt
MIT License
1.08k stars 30 forks source link

Clarification on how `D.get` works when key exists but value is undefined #75

Open eLysgaard opened 1 year ago

eLysgaard commented 1 year ago

I have some trouble using D.get and I'm unsure if this is a bug or if I'm misunderstanding the documentation.

Here's a minimal example to show the issue I'm having

const foo: {bar: string | undefined} = {bar: undefined};
pipe(
  foo,
  D.get('bar'),
  O.map(value => value.length) // The type of "value" is string, but its actual value is undefined so it throws
)

I can see the documentation says

Returns Some(value) if the given key exists, otherwise returns None.

In the above example the key does exist, and based on the return type of D.get I guess it becomes ExtractValue<string | undefined> which would end up as Exclude<string | undefined, null | undefined | void> resulting in string, which does not correspond to the actual value being passed to O.map

To resolve this I've gone ahead with the following solution.

const foo: {bar: string | undefined} = {bar: undefined};
pipe(
  foo,
  D.get('bar'),
  O.fromNullable, // This seems to properly wrap the undefined value from `foo.bar` in Option
  O.map(value => value.length) // The type of "value" is string, but its actual value is undefined so it throws
)
JUSTIVE commented 5 months ago

seems that it's option's problem, related to #97