gigobyte / purify

Functional programming library for TypeScript - https://gigobyte.github.io/purify/
ISC License
1.53k stars 59 forks source link

Fix: update types for typescript 5.5 support #714

Closed benvan closed 4 months ago

benvan commented 4 months ago

Typescript 5.5 changed the assignability of type predicates - it means that isJust(): true is no longer a subtype of isJust(): this is AlwaysJust

This PR adds type predicates to Either and Maybe (which are the only two types affected)

Major caveat

I am worried this might be a breaking change. As far as I can tell, there is no way to achieve the old behaviour of knowing at compile-time that a Just returns true (as const) from isJust

benvan commented 4 months ago

Related: https://github.com/gigobyte/purify/issues/711

gigobyte commented 4 months ago

Can you give more information about the caveat? On my machine this works:

const j = Just(5)
    if (j.isJust()) {
      const value: number = j.extract()
    }
    // @ts-expect-error
    const value2: number = j.extract()
benvan commented 4 months ago

To be honest, on reflection I'm no longer sure it matters. There is, academically, a potential breaking change - but i'm not sure how widespread it's likely to be.

This is the scenario I was thinking of - where somebody has explicitly relied on the true or false types. My example uses Nothing, but it applies to Either / Left / Right as well I think

type AlwaysJust = {__:symbol}

declare class NothingV1 {
  isJust(): false
}

declare class Nothingv2 {
  isJust(): this is AlwaysJust
}

// (I've explicitly made this a separate type rather simply using NothingV1, because in reality anybody referencing "Nothing(V1)" would now be referencing "Nothing(V2)"...)
type DefinitelyNothing = { isJust(): false }

declare function expectNothing(v: DefinitelyNothing): void

declare let v1: NothingV1
declare let v2: Nothingv2

// code using this approach compiled before
expectNothing(v1)

// but it will break with this change
expectNothing(v2)

Just to reiterate: This update could break code for people on < 5.5, but the chances seem low