Need help with typescript stuff

I am trying to implement the Maybe monad in typescript. It's like the Option type in Rust. Here's what I have so far:
const None = Symbol("None");

export class Maybe<T> {
constructor(private value: T | typeof None) {}

static some<T>(value: T): Maybe<T> {
if (value === null || value === undefined) return Maybe.none<T>();

return new Maybe<T>(value);
}

static none<T>(): Maybe<T> {
return new Maybe<T>(None);
}

static from<T>(value: T): Maybe<T> {
if (value === null || value === undefined) return Maybe.none<T>();

return Maybe.some(value);
}

public match<U>({ some, none }: { some: (value: T) => U; none: () => U }): U {
if (this.value === None) return none();

return some(this.value);
}

public map<U>(fn: (value: T) => U): Maybe<U> {
if (this.value === None) return Maybe.none<U>();

return Maybe.some(fn(this.value));
}

public flatMap<U>(fn: (value: T) => Maybe<U>): Maybe<U> {
if (this.value === None) return Maybe.none<U>();

return fn(this.value);
}

public getOrElse<U>(value: U): T | U {
if (this.value === None) return value;

return this.value;
}
}
const None = Symbol("None");

export class Maybe<T> {
constructor(private value: T | typeof None) {}

static some<T>(value: T): Maybe<T> {
if (value === null || value === undefined) return Maybe.none<T>();

return new Maybe<T>(value);
}

static none<T>(): Maybe<T> {
return new Maybe<T>(None);
}

static from<T>(value: T): Maybe<T> {
if (value === null || value === undefined) return Maybe.none<T>();

return Maybe.some(value);
}

public match<U>({ some, none }: { some: (value: T) => U; none: () => U }): U {
if (this.value === None) return none();

return some(this.value);
}

public map<U>(fn: (value: T) => U): Maybe<U> {
if (this.value === None) return Maybe.none<U>();

return Maybe.some(fn(this.value));
}

public flatMap<U>(fn: (value: T) => Maybe<U>): Maybe<U> {
if (this.value === None) return Maybe.none<U>();

return fn(this.value);
}

public getOrElse<U>(value: U): T | U {
if (this.value === None) return value;

return this.value;
}
}
Here the from method is used to take in a value and convert it to a Maybe<value>. For example:
const a = Maybe.from(9);
// ^? const a: Maybe<number>

const b = Maybe.from("hi");
// ^? const b: Maybe<string>
const a = Maybe.from(9);
// ^? const a: Maybe<number>

const b = Maybe.from("hi");
// ^? const b: Maybe<string>
But there's a problem, when I pass a value that could either be some type (like number, string, etc) or null or undefined, it returns Maybe<value | undefined>. The Maybe monad handles this by using none so there's no need to have Maybe<value | undefined>, it just needs to be Maybe<value> . For example:
const z = Maybe.from([1, 2, 3].pop()); // z is Maybe<number | undefined> but I want Maybe<number>
const z = Maybe.from([1, 2, 3].pop()); // z is Maybe<number | undefined> but I want Maybe<number>
How do I modify my code in order to implement this behaviour? Playground link: https://www.typescriptlang.org/play?#code/MYewdgzgLgBAcuApjAvDAygTwLYCMQA2AFAEQJiIkCUA3AFB2IAeADiAE6zAECGEEMALI9MuRAB4AKgD4YAbzowYoSFHYBXYFA5EW7AJYA3HlGTGC6xAC4YkmAB8YUTC0QgAZvCRV5AXwZK0Cb6wDAQINgSMkTmljaSVDbColGyCkpK+p4xPBbIKAUwYOoEBA6OsfmF6mAAJoju+hS1PuyIUOrsYEIiYgB0YEhS0kS0ARltHV1FiADuPSnDOXljSv6KYVDBoYMUS4kLYsPyG0qTnd0U88lH0eSIqzDrgVtQITDu7BFLlfEHN6kThkYFkYMtLKhCsVSuUYJVIWgavVGs1Wu0LodEAMhtExqcYOdpgC+uFIuCHvQ1uMWOpcAR3tgTMAABbiACqIzkYQiiAANEUkE8bFzSdYwb9bD4ULI2TQBRQbKNUDKngc2UCMqCiFBmfoIH14QU0Pc0VNLkhRvR8YTuqLtbr9ZVHs8YDS6QyeCx2SN3GBFRKEsqYGz-r0JByNZlsjq9QbchCjV4KKaMcTduGRnjgTbMSSeURffbY07ndTafTQu5eFBhF6OQW-eL42LA9LMd7Q4sI+lNdGHXG8gikw8CeiiWHsXt61mJmPuoWY47m6WNm6KzAAObtADy7AAogQIBnyTYQ-EHMHIyC+8Xm0OTaOzXDm1bs3OnP3KpSnnR1ipoDATCoLmnwREQADaACM-IAEz8gAzAAun0bAsKMYwAPQYcCAB6AD8QA
TS Playground - An online editor for exploring TypeScript and JavaS...
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
15 Replies
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
nexxel
nexxelOP2y ago
not super familiar with Omit lemme look it up
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
nexxel
nexxelOP2y ago
is this how it would be used?
static from<T>(value: T): Omit<Maybe<T>, "undefined"> {
if (value === null || value === undefined) return Maybe.none<T>();

return Maybe.some(value);
}
static from<T>(value: T): Omit<Maybe<T>, "undefined"> {
if (value === null || value === undefined) return Maybe.none<T>();

return Maybe.some(value);
}
nexxel
nexxelOP2y ago
probably using it wrong cause this still can be undefined https://this-vegetable.is-from.space/Alacritty-v0.10.0-portable_(1)_xDQClClw7i.png
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
nexxel
nexxelOP2y ago
yeah
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
nexxel
nexxelOP2y ago
i fixed it i think?
static from<T>(value: T | null | undefined): Maybe<T> {
if (value === null || value === undefined) return Maybe.none<T>();

return Maybe.some(value);
}
static from<T>(value: T | null | undefined): Maybe<T> {
if (value === null || value === undefined) return Maybe.none<T>();

return Maybe.some(value);
}
just extending the param type to be either T or null or undefined fixed the type errors
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
nexxel
nexxelOP2y ago
this is interesting lol
nexxel
nexxelOP2y ago
nexxel
nexxelOP2y ago
but didn't need to do the assert part
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
nexxel
nexxelOP2y ago
yeah me too
Want results from more Discord servers?
Add your server