Code won't compile with resi file present, but remove that and it compiles with no issues?

Ran into something peculiar here.

This is the gist of the code, which compiles fine in rescript playground ReScript Playground (rescript-lang.org)

My project won’t compile while the .resi file is present or the specification for remove_value_from_el_at_idx_and_update/2 is present in the .resi file.

There I tried messing around with just returning None from remove_value_from_el_at_idx_and_update/2 with the specification still present in the .resi file, and that works, but whenever I try returning a Some the compilation error pops up.

Compiles with no issues

let remove_value_from_el_at_idx_and_update: (array<remove_and_update_list_interface<'collection, 'a>>, int) => option<('a, array<'collection>)>
    = (xs, idx) => {
        let ys: array<'collection> = xs->Js.Array2.map(x => x.collection)
        None
    }

while this will cause a compilation error

let remove_value_from_el_at_idx_and_update: (array<remove_and_update_list_interface<'collection, 'a>>, int) => option<('a, array<'collection>)>
    = (xs, idx) => {
        let ys: array<'collection> = xs->Js.Array2.map(x => x.collection)
        Some((1, ys))
    }

yields the compilation error:

  The implementation C:\Users\jgood\Desktop\dev\candle-aggregation-res-v2\src\utils\CandleAggregationUtils.res
       does not match the interface src\utils\candleAggregationUtils-CandleAggregation.cmi:
       Values do not match:
         let remove_value_from_el_at_idx_and_update: (
  array<remove_and_update_list_interface<'collection, int>>,
  int,
) => option<(int, array<'collection>)>
       is not included in
         let remove_value_from_el_at_idx_and_update: (
  array<remove_and_update_list_interface<'collection, 'a>>,
  int,
) => option<('a, array<'collection>)>
       File "C:\Users\jgood\Desktop\dev\candle-aggregation-res-v2\src\utils\CandleAggregationUtils.resi", line 19, characters 1-144:
         Expected declaration
       File "C:\Users\jgood\Desktop\dev\candle-aggregation-res-v2\src\utils\CandleAggregationUtils.res", line 157, characters 5-43:
         Actual declaration

I hope I’m not missing something glaringly obvious.

can you come up with a repro in the playground?
All you have to do to simulate a .resi file is to wrap your code inside a module and add a signature to it.

https://rescript-lang.org/try?version=v10.1.2&code=LYewJgrgNgpgBAFwJ4Ad4EkB2CYCcBmAhgMbwC8cA3gFACQyacuMoAbjAPqGZgcQphCODlACWAZwQdR2PEVIAeAOTEQUWMQSiQmADRwlhAHxwKNOBcur1MTdswAuA9Y1adu6pcvM2MJwAoVNVd7UxMQFDdMBUDCfTFJZWMASiNksLgIqJjDeIkEJLSjDy8LfkEcJwSCwxMyEyCbOx1POABfalbYBCYWEHYOVkIoCE58XBBgDhgoLilRMAAPLh4+ASE-OH9W0rhCXFxCJAUffs5uXnKNkXzpWQISGGUXWyj9WuKd0pkEEst0+qZSL2HJxPYHI7PYKvexFCzUDrUUCQWBwdDAFBQJxYHAPUimKhdGA9cSEfCcADmxIC+0Ox1q+h+APCwJ0hS+FH8i3EjKWzMJuwsCFwSAFgq8AGVJjAueIANoLRYAXWSXy8bTgxCExAAFmLxRYAD5wDgZAByOhgassHXVnW6vV8HHwolwkmdEym1Sq+UKGSyINieUStVSHK23P54gA7qIELq4Nz9aVjdVKBrARbMFbxan8pQXW7fnAAHRlnyEGQyCkZkxS4Ay-yFyT6CtVzAU5Kqu3UB3MTGPaazGRcCFIObSJY0seFRnYd6Efm0yG1cOypzL+nGXmLJw-fS7gyLjLmQUOyT7HoUABS4hLAEExwAmEviMSkWX6AB+F9wCDIAAM34wKsZCKt2Z7EnAIFgASt4Ps+r7vjK3Lfr+-6KgA1AAjMBoEALTYRBuzwY+dIvqomBaggACy3BIP46H6HKcrKvoMEql8iIMPApwDBcawVJw1R3Li8hPI0ITuEedTJi8zSOM40IKX8Fh8ZsgTyVE-qstEQZwNUhSpPyAZsvphmhp8XhXJUBm+rUGSSTCLSIn2fQDEMIxjJ6Q4ToqKyXOstnbOKm4nO55yrDZwm3D8ciPFCTRvDJVmCvuXwmbpoL6GFTkKUUa6oXAip7tgzLWhYMZxgmpLkhwVIIJ+xV8smuZwPWMrAII-KngapQOoepl6bk4J0olUmYHCFBVfGepdYQJbqf46nOq67rjJMNySOkvV9YKxodf4TZrcWbaYNWXYnhVe27ANTh5dpFDzSW0XLSwlbnR2xE3QaDpIOIG4zg9sIEty+FGKRiHAIQKBchkiwllp9jfT9kE9NFYCA2NwM6LJ-ZQIOMx3KOdJ+Us-j-TuB7pNdqMWIdx1FvoGNdrTe22nTXjGlm5AmDzbO7IinOLAL7Si9zlrmpa10dB0QA

Okay, I did miss something glaringly obvious, but weird that the implementation of remove_value_from_el_at_idx_and_update didn’t cause this to fail to compile when not using a .resi file.

This

type remove_and_update_list_interface<'collection, 'a> = {
    collection: 'collection,
    remove: ('collection => option<('a, list<'a>)>) => option<('a, list<'a>)>,
    update: list<'a> => 'collection
}

Needed to be updated to this

type remove_and_update_list_interface<'collection, 'a> = {
    collection: 'collection,
    remove: (list<'a> => option<('a, list<'a>)>) => option<('a, list<'a>)>,
    update: list<'a> => 'collection
}

Because

let remove_value_from_el_at_idx_and_update: (array<remove_and_update_list_interface<'collection, 'a>>, int) => option<('a, array<'collection>)>
    = (xs, idx) =>
        switch Utils.safe_get(xs, idx) {
            | Some(mda) => {
                let x: option<('a, array<'collection>)> = switch mda.remove(Utils.remove_first_from_list) { // remove_first_from_list: list<'a> => option<('a, list<'a>)>, would've suspected a compiler error from this with the first type spec of remove_and_update_list_interface
                    | Some((first, remaining)) => {
                        let x: 'collection = mda.update(remaining)
                        let ys: array<'collection> = xs->Js.Array2.map(x => x.collection)
                        let updated: array<'collection> = Utils.replace_el_in_array_at_idx(ys, idx, x) 
                        Some((first, updated))
                    }
                    | None => None
                }

                x
            }
            | None => None
        }

the compilation did not fail because 'collection got inferred as list<'a>