Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Be strictNullChecks compatibility #52

Open
JohannesHome opened this issue Jun 19, 2018 · 11 comments
Open

Be strictNullChecks compatibility #52

JohannesHome opened this issue Jun 19, 2018 · 11 comments

Comments

@JohannesHome
Copy link

Currently, when using this library with the flag enabled we have the following issue:

const object: { value: number | null } = { value: null };

const result: number | null = Maybe.maybe(object)
            .map(obj => obj.value)
            .valueOr(10);

As you can see result keeps the type null, since the current typings reflect this. It would be nice if the type for map could reflect the removal of null. Example:

    map: <U>(f: (t: T) => U | null) => Maybe<U>;

I saw that in #31 this point has been mentioned and fixed for Maybe.maybe but not in general.

Currently there is not a single optional or maybe typescript library out there that is fully strictNullChecks compatible.

My question, is this planned?

@patrickmichalina
Copy link

Working on an alternative library with pretty similar functionality and modern TS support:

https://github.com/patrickmichalina/typescript-monads

@JohannesHome
Copy link
Author

@patrickmichalina yeah, we can all build our own library, just kinda defeats the purpose :)

Hmm, looking at your code, I think it also only handles undefined not null. Also I think it might swallow empty strings, 0, and false and there seems no way to map the wrapped value, as map looks like a flatMap.

@patrickmichalina
Copy link

If people kept up on their repos, it wouldn’t be necessary :)

I’ll check out your comments and adjust accordingly. Thanks.

@Ailrun
Copy link

Ailrun commented Aug 28, 2018

@patrickmichalina @JohannesHome Sorry for bothering you with same repeated idea. I recently built https://github.com/Ailrun/typed-f and I believe these packages satisfy all usage with strictNullChecks.
However, this package is still in 0.* version so I need more helps from forks. If you are willing to, please take a look 😄

@JohannesHome
Copy link
Author

@Ailrun looks good, but it it isn't type safe. Simple example is already the signature for Maybe.from(value?: null): Nothing<any>;, it should infer the type base on the input parameter instead of using any.

This let's me do stuff like this:

    const test: string | undefined = undefined;
    const from = Maybe.from(test);
    const result: string = from.valueOr(1);

without a compile error. Also the docs could be more comprehensive.

And yeah I know I can force the type with Maybe<string>, but it's nicer if the monad infers the type 😄 (less work for me)

@Ailrun
Copy link

Ailrun commented Aug 29, 2018

@JohannesHome Oh, thank you for feedback.
However, even with following type,

Maybe.from<T>(value?: null): Nothing<T>;

Following code will give you wrong type.

const test: string | undefined = undefined;
const from = Maybe.from(test); // This will give you Nothing<{}>

Though it will give you an error for following statement.

const result: string = from.valueOr(1); // Complain about that `{}` cannot be assigned to `string`.

@Ailrun
Copy link

Ailrun commented Aug 29, 2018

@JohannesHome Following code will give you better explanation.

function x(test: string | undefined) {
  const from = Maybe.from(test);
  return from.valueOr(1); // Give you an error!
}

Your code works since TS think your test as just undefined, and that's why following also works in TS.

const test: string | undefined = undefined;
const x: number | undefined = test;

@JohannesHome
Copy link
Author

@Ailrun this is a bit out of scope but your library could infer the type based on the actual value like so Maybe.from<T>(value?: T): Nothing<T> which is the same as Maybe.from<T>(value: T | undefined): Nothing<T>, this allows the compiler to infer the type correctly and making it typesafe without having to specifying the return type (something I like to forget).

@Ailrun
Copy link

Ailrun commented Aug 29, 2018

@JohannesHome These are all because TS knows what the value of test is in compile time, since you declare const test: string | undefined = undefined. As I said, TS consider this test as undefined, so you can assign this value to any type that accepts undefined. You already loose your string type.

@Ailrun
Copy link

Ailrun commented Aug 29, 2018

However, if it's still unclear to you, could you open an issue on my repo? Explaining things related with my code in this repo feels somewhat weird for me 😅
Ailrun/typed-f#46

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

No branches or pull requests

3 participants