0

Here the accepted answer says that:

And the quirk of excess property checks is that for unions, it allows any property from any union constituent to be present in the assigned object literal.

But in this example:

  type LoadingState = { isLoading: true };
  type SuccessState = { isLoading: false; isSuccess: true };
  type ErrorState = { 
    errorMessage: string;
  };

  type State = LoadingState | SuccessState | ErrorState ;

  let x: State = {
    isLoading: false,
    isSuccess: true,
    errorMessage: '',
  };

Why am I getting following error?

Type '{ isLoading: false; isSuccess: true; errorMessage: string; }' is not assignable to type 'State'. Object literal may only specify known properties, and 'errorMessage' does not exist in type 'SuccessState'

errorMessage comes from one of the unions as mentioned in that answer.

Extra: Another strange thing if I modify the State type like this:

  type State = SuccessState | ErrorState ;

error goes away.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
  • Excess property checks normally occur on *discriminated* unions, but not on non-discriminated unions. The type `LoadingState | SuccessState | ErrorState` isn't fully a discriminated union, but `LoadingState | SuccessState` is, so I imagine what's happening is that you're getting some hybrid behavior where the discriminated portion is triggering excess property checks. But this is a weird edge case (or at least not one I've seen much) so I don't know how to answer authoritatively. – jcalz Feb 17 '23 at 17:22
  • Current excess property checking on unions is a mish-mash of heuristics; there was some work done at https://github.com/microsoft/TypeScript/pull/23798 to make it always happen, but it was never merged. Let me know if you want any of this written up as an answer. – jcalz Feb 17 '23 at 17:23
  • @jcalz Hm but the accepted answer in the SO post I linked to in my question didn't say anything about discriminated unions right? – Giorgi Moniava Feb 17 '23 at 18:02
  • Right, but there are other answers, one of which mentions making it a discriminated union to get the excess property warnings (and the author of the accepted answer says " Making a discriminated union is definitely also a valid idea") – jcalz Feb 17 '23 at 18:04
  • @jcalz So you suggest accepted answer might not be accurate? (because it says TS ignores excess properties if they belong to one of the unions) – Giorgi Moniava Feb 17 '23 at 18:12
  • It might not be *complete*. If not mentioning every exception makes an answer *inaccurate* then I don't know if I've ever written an accurate answer myself. – jcalz Feb 17 '23 at 18:16
  • @jcalz hm do you think it is worth making a github issue on TS repo? Also the other answer you mentioned on that SO post, if you check comments beneath it, there is my comment, where I encountered those discriminated unions don't work when the `type` is dynamic. – Giorgi Moniava Feb 17 '23 at 18:26
  • If you don't think the issue https://github.com/microsoft/TypeScript/issues/20863 or any of the issues linked to it bring up the particular situation you're dealing with, then yes, but my guess is that it would still be closed as a duplicate of one of those – jcalz Feb 17 '23 at 18:36
  • @jcalz To make clear so you are saying that excess properties are reported on discriminated unions, but they might be ignored (assuming they come from other unions) in case of non discriminated unions right? – Giorgi Moniava Feb 17 '23 at 18:46
  • Yeah, that's the general behavior. – jcalz Feb 17 '23 at 19:34
  • @jcalz in your first comment I think you wanted to say that `SuccessState | ErrorState` isn't a discriminated union right? instead of saying `LoadingState | SuccessState` is. Because that's the case I reported in *extra*. – Giorgi Moniava Feb 17 '23 at 20:17
  • I just reread it and I said what I meant to say. I wasn't looking at *extra*; that isn't a discriminated union at all. So you have discriminated unions like `L | S` (excess property errors happen) and non-discriminated unions like `S | E` (excess property errors don't happen) and then you have `L | S | E` which isn't a discriminated union but it's sort of *partially* one, where I don't know what "should" happen. Excess property errors are kind of linter rules anyway; they aren't needed for type safety. – jcalz Feb 17 '23 at 20:20
  • BTW I will probably stop engaging here soon unless it's as part of a process for my writing up an answer. Otherwise we're just chatting and that's not appropriate for SO. – jcalz Feb 17 '23 at 20:21
  • @jcalz I see. As for writing up an answer, feel free to do so. But if you feel like you can't write it authoritatively, we can as well leave the info in comments. If you write an answer I will definitely upvote it. But sometimes I am also reluctant to accept answers if I don't feel they are authoritative enough. – Giorgi Moniava Feb 17 '23 at 20:26

0 Answers0