typescript-go icon indicating copy to clipboard operation
typescript-go copied to clipboard

Discrepancies in behavior of spread of union type

Open benjaminjkraft opened this issue 4 months ago • 0 comments

type State =
  | { loaded: true; type: "loader"; value: string }
  | { loaded: false; type: "loader" }
  | { type: "other" };

declare class Store {
  state: State;
  setState(state: State): void;
}

function unload(store: Store): void {
  store.setState({ ...store.state, loaded: false });
}

This passes in TS, in Go we get:

src/union.ts:12:36 - error TS2353: Object literal may only specify known properties, and 'loaded' does not exist in type '{ type: "other"; }'.

12   store.setState({ ...store.state, loaded: false });
                                      ~~~~~~

(It's a bit debatable who's philosophically more correct -- it depends on which objects are allowed to have unknown properties. But I haven't been able to construct a case that TS is okay with where the code produces an invalid value if we assume all unknown properties are allowed, so I'm guessing this is all intended behavior in TS.)

benjaminjkraft avatar Jun 02 '25 23:06 benjaminjkraft