Skip to content

Discrepancies in behavior of spread of union type #1020

Closed
@benjaminjkraft

Description

@benjaminjkraft
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.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: Type CheckingRelated to type checking, grammar checkingbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions