rescript-compiler icon indicating copy to clipboard operation
rescript-compiler copied to clipboard

Record spread from smaller to bigger record type set doesn't work

Open ryyppy opened this issue 2 years ago • 6 comments

I observed some weird behavior while working on my app, so I tried to reduce the problem to a minimal example.

type a = {
  title: string,
  ingredients: array<string>,
}

type b = {
  ...a,
  parsedIngredients: array<string>,
}

// This works
let a: a = {
  title: "Pizza",
  ingredients: ["1 EL Oil", "1 EL flour"],
}

// EXPECTED: This should compile
let b: b = {
  // ERROR: This has type `a`, but it's expected to have type `b`
  ...a,
  parsedIngredients: ["Oil", "Flour"],
}

I don't know if I misunderstood the record type spread feature, but IMO from an intuition perspective I'd expect value b to initialize just fine, since we are essentially spreading in all the values that a has, plus the parsedIngredients value that's required from b.

Does this work as expected?

ryyppy avatar Dec 03 '23 20:12 ryyppy

cc @cristianoc who can explain this better than me, but this is the current state:

  • The new record type spreads is only at the type level. This example is a runtime thing
  • Can't go from a to b here for a because it's not a subtype (missing required parsedIngredients)

So that's the current state. Nothing exists to handle what you're asking about essentially.

I do agree with you however that this type of functionality would feel natural. I guess it could be the equivalent of inlining all of the fields and values of a into b in the compiler at the time of spreading. Looking at it, it definitively feels like this is something that'd be good if one could do.

zth avatar Dec 03 '23 21:12 zth