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

Add Optional type #31

Open
EladBezalel opened this issue Apr 23, 2019 · 16 comments
Open

Add Optional type #31

EladBezalel opened this issue Apr 23, 2019 · 16 comments
Labels
core Basic types you’d think were part of the standard lib help wanted Extra attention is needed type addition

Comments

@EladBezalel
Copy link

EladBezalel commented Apr 23, 2019

An optional type is really missing in the context of return types,
When a function might a value or not you find yourself piping undefined

type Maybe<T> = T | undefined;

Can be really useful

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@BendingBender
Copy link
Contributor

@EladBezalel What about null?
@sindresorhus Too trivial?

@EladBezalel
Copy link
Author

I'd make a separate type Nullable<T>

@BendingBender
Copy link
Contributor

Sorry about this but when I think about a Maybe type I have usually something in mind that resembles the functional variant of it, also called Optional.

Any ideas for a less overloaded name?

@BendingBender
Copy link
Contributor

And just looking at the type, it is so trivial that it actually sacrifices readability in favor of saving a few keystrokes. Now, everyone reading this has to look it up instead of directly and unambiguosly understand it.

This is a clear NAK from my side. @sindresorhus has the final word on it.

@EladBezalel
Copy link
Author

As far as i see it it's very self explanatory, once you find out that type you understand it and use it.

As for the naming i wanted something that implies - you either get T or get nothing
That's why i thought Maybe T is really readable

@sindresorhus
Copy link
Owner

If we were to add it, I would call it Optional and the nil case would be undefined, not null.

I've been wanting this type since I started using TypeScript. I also initially found it surprising that type Foo = number? didn't work. However, I agree with @BendingBender. The only way it makes sense is for it to be a built-in. Without, it's just a type that saves a few characters in favor decreased usability and readability. It's only useful if everyone uses the same naming and everyone knows what it means. That can only happen if it's a built-in type. Another thing that could happen if it was a built-in is syntax sugar like type Foo = number?.

I would strongly encourage you to open an issue on TypeScript about adding this type.

@sindresorhus sindresorhus changed the title Add Maybe for generic or undefined Add Optional type Jul 2, 2019
@JoBrad
Copy link

JoBrad commented Sep 5, 2019

I use a Maybe as a result type for quite a few of my utility functions that are designed to return undefined if certain conditions aren't met. I usually define it as type Maybe<T> = NonNullable<T> | undefined to explicitly note that a null value is not an acceptable response.

It's all semantics, of course, but for result types I prefer Maybe, while using Optional for input values.

@sindresorhus
Copy link
Owner

sindresorhus commented Sep 16, 2019

I have reconsidered and I think we should add this. While I wouldn't recommend using it in reusable packages, and I think we should clearly discourage it for open source projects, it can be a nice utility for large internal projects where everyone knows what it means. It would also be nice to have it here as an example on how to implement it correctly. And it can be a good way to push TypeScript to add it if more people are exposed to its usefulness and start using it in their code.

I think we should go for:

type Optional<T> = NonNullable<T> | undefined;

Alternatively: (Which inlines NonNullable without the undefined exclusion)

type Optional<T> = T extends null ? never : (T | undefined);

Opinions on which? I'm leaning towards the latter.


If you wanna do a PR for this, please read https://github.com/sindresorhus/type-fest/blob/master/.github/contributing.md thoroughly and look at previous PR additions.

@sindresorhus sindresorhus added enhancement New feature or request help wanted Extra attention is needed labels Sep 16, 2019
@CarsonF
Copy link

CarsonF commented Oct 17, 2019

FWIW I like

type Nullable<T> = T | null | undefined;

Which is just the exact opposite of NonNullable.

I typically don't mind having the type as null or undefined because those are usually handled the same way. My use case is this:

const upper = (str: Nullable<string>) => str ? str.toUpperCase() : null;
interface Obj {
  foo?: string;
  bar: string | null;
}
const obj: Obj;
upper(obj.foo);
upper(obj.bar);

@sindresorhus
Copy link
Owner

@CarsonF Including null is not going to happen for reasons outlined here.

@CarsonF
Copy link

CarsonF commented Oct 17, 2019

Thanks for the link. I know what I'll be thinking about the rest of the day 😉

@chriszrc
Copy link

Has this happened?

@sindresorhus
Copy link
Owner

The issue is still open.

@chriszrc
Copy link

@sindresorhus didn't you outline your own thoughts on this here:

#31 (comment)

What else is there to do?

@sindresorhus
Copy link
Owner

What else is there to do?

The actual work.

The issue is accepted, but someone has to take the time to write a description, high-quality docs, examples, etc.

@Xample
Copy link

Xample commented Jan 26, 2023

@BendingBender
There is the Nullish operator in JS which makes no distinction between "undefined" and "null".

Optional: should only mean it can be defined or not (undefined)
Nullable means it is always defined, but we might want to explicitly have nothing as a value.

Metaphor: I have received no letter (undefined) vs I've received an empty letter (null), both are different concept, but the outcome is still "I've nothing to read", this is precisely why we (sadly) don't really pay attention to either one or the other.

Therefore (#318):

type Nullish = undefined | null;
type MaybeNullish<T> = T | Nullish;

or

Maybe<Nullable<T>>

@fregante fregante added type addition core Basic types you’d think were part of the standard lib and removed enhancement New feature or request labels Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Basic types you’d think were part of the standard lib help wanted Extra attention is needed type addition
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants