1

In ReasonML option type is a variant which can either be Some('a) or None.

How would I model the same thing in typescript?

  • 1
    technically, `Optional` would just be `MyType | null` for example. So, you can do `type Optional = T | null`. However, I don't think that's quite as helpful as an actual optional type - you probably want something more robust. – VLAZ Oct 23 '20 at 10:17
  • 1
    @KonradRudolph I don't think OP means optional properties. An optional *type* is a result that either might be there or not. It is a more explicit version of a `null` which is an absence of value. Depending on the language, there might be better null-safe handling about it where if something returns `None`, you can still chain more operations that resolve as a no-op, rather than having to manually do type checks all the time or adding null guards. – VLAZ Oct 23 '20 at 10:20

2 Answers2

1

Perhaps, something like this:

export type None = never;

export type Some<A> = A;

export type Option<A> = None | Some<A>

If you're interested in functional programming with ts, you could take a look at fp-ts

  • 1
    I like this idea at a high level, but I don't think you want `never` as `None`, since presumably it's possible for the variable/property/return value to have the "none" value -- otherwise you lose the whole point of Optional. I'm not sure what you'd use instead other than `undefined` or `null`, though, which somewhat begs the question of having the type... Usually there's more to an Optional type than this. – T.J. Crowder Oct 23 '20 at 10:26
  • I was thinking about using null as None, but wasn't sure how would OP mark the None value. Anyway, I left the link to the package I would choose, if I was interested in using monads from fp – Yesset Zhussupov Oct 23 '20 at 10:31
  • 1
    I'd echo the concerns of @T.J.Crowder - I don't think `never` is a good fit here. Usually, you want an `Optional` when you *can* handle either case, so you'd have `getFromDb(id: number): Optional` and you can more uniformly handle the result as `getFromDb(42)?.name`. This isn't possible with `never` but it *is* if you return `null`. Then again, optional types aren't really about optional chaining - the previous code should return a `Optional` that you can continue operating with without worrying for nulls until you "unwrap" it. – VLAZ Oct 23 '20 at 14:40
1

TypeScript doesn't have a direct equivalent. What you'd do instead depends a bit on what you're using it for: A property, a function parameter, a variable or function return type...

If you're using it for a property (in an object/interface), you'd probably use optional properties, for instance:

interface Something {
   myProperty?: SomeType;
//           ^−−−−− marks it as optional
}

The same notation works for function parameters.

For variables or return types, you might use a union type with undefined or null, e.g.:

let example: SomeType | undefined;
// or
let example: SomeType | null = null;

The first one says that example can be of type SomeType or undefined, the second say it can be SomeType or null. (Note the latter needed an initializer, since otherwise example would be undefined, and that isn't a valid value for SomeType | null.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875