#Type narrowing from "in" operator check

10 messages · Page 1 of 1 (latest)

undone schooner
#

Should TS infer the correct type of a property in an object based on an in check?

type test = {
  name?: string | undefined;
};

type test2 = {
  name?: string;
};

declare const kTest: test;
declare const kTest2: test2;

if('name' in kTest) {
  const myVar = kTest['name']; // myVar is of type: string | undefined
}

if('name' in kTest2) {
  const myVar2 = kTest2['name']; // myVar is of type: string | undefined
}

Shouldn't myVar2 be of type string, and not string | undefined based on the in operator check?

In other words, the ? operator in a type should resolve to T rather than T | undefined given an in operator check

#

Type narrowing from "in" operator check

forest stag
#

ts treats optional props as T | undefined

#

test and test2 are essentially equivalent here

undone schooner
#

Right, but I'm arguing that shouldn't be the case. There's a difference between having name be defined in an object and being set to undefined, vs having name not be defined in an object, and returning undefined when a property accessor is used

#

So essentially, TS is not distinguishing between properties defined in an object and not defined

forest stag
#

there's a difference yes
ts does make the distinction, no
it just doesn't make the distinction for optional properties

odd comet
#

@undone schooner You're looking for the exactOptionalPropertyTypes flag.

granite loomBOT
#


// with @exactOptionalPropertyTypes

if('name' in kTest) {
  const myVar = kTest['name'];
//      ^? - const myVar: string | undefined
}

if('name' in kTest2) {
  const myVar2 = kTest2['name'];
//      ^? - const myVar2: string
}