1

I ran into a problem while defining a value for a constant. Despite the specified type, Typescript does not throw an error and I think it should. I have prepared a code that presents my problem. I believe line 14 should be reported as an error because the "valueN" property is missing.

//example
type TT = string | {string_:'S', valueS:string} | {number_:'N', valueN:number};

function run(p:TT):number{
    if(typeof p === 'string'){
        throw '';
    }
    if('number_' in p){
        return p.valueN;
    }
    throw '';
}

const C:TT = {number_:'N',string_:'S',valueS:'text'};

console.log(run(C));

Playground

Can someone explain to me why TS behaved like this, and how to improve the code so that line 14 reports an error for the missing property.

Nick Vu
  • 14,512
  • 4
  • 21
  • 31
logrox
  • 13
  • 2
  • FYI, here's how you might use a discriminated union: https://tsplay.dev/wOxYrN Note that there's no need for the suffix on `value` (although of course you could have it if you want). – T.J. Crowder Jan 11 '23 at 08:45

1 Answers1

0

const C is compatible with TT because it fits type {string_:'S', valueS:string} from the union type TT, with an extra property number_:'N'. Extra properties are allowed, so no error. Maybe you need something like discriminated union for your case?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Nikolay
  • 3,658
  • 1
  • 24
  • 25
  • "Extra properties are allowed" relevant: https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks – VLAZ Jan 11 '23 at 08:27
  • @VLAZ - Do you know why excess property checks didn't apply in this case? After all, `const C: { type: "string"; valueS: string } = { number_: "N", string_: "S", valueS: "text" };` would trigger the excess properties error. Is it because `TT` is a union? – T.J. Crowder Jan 11 '23 at 08:33
  • 1
    @T.J.Crowder because of the union would be my guess as well. I don't really know. I was more trying to add context that extra properties are not always allowed. And I really don't know why they are here. – VLAZ Jan 11 '23 at 08:35
  • The answer would be markedly strengthened by an example of a discriminated union. But it turns out the question is already answered elsewhere. – T.J. Crowder Jan 11 '23 at 08:38
  • 1
    @VLAZ - Thanks, that's indeed what Titian says in the dupetarget, but with the proviso that **only** excess properties from other members of the union are allowed. I'd call that a bug, but... – T.J. Crowder Jan 11 '23 at 08:39