ale917k
ale917k

Reputation: 1768

TS: Assert on condition scope

I have a similar situation,

type Field1Type = {
   a: string;
}

type Field2Type = {
   b: string;
   c: number;
}

type ObjType = {
   field: Field1Type | Field2Type
}

const field = {
   b: ""
   c: 0
}

const obj = { field } as ObjType

if (some_condition) {
   // TS compiler errors out: Property 'b' does not exist on type 'Field1Type'.ts(2339)
   console.log(obj.field.b)
}

Where I essentially have an object with an object field which can take different types.

When accessing the field properties, I get the TS warning for a valid reason since it doesn't know if that field type is either Field1Type or Field2Type.

That could be fixed as followed,

if (some_condition) {
   const temp = obj.field as Field2Type

   // TS compiler errors out: Property 'b' does not exist on type 'Field1Type'.ts(2339)
   console.log(temp.b)
}

But it doesn't really look like a clean solution.

Question, is it possible to assert the field inside the condition in a nicer way?

Upvotes: 0

Views: 235

Answers (1)

Indraneel Pole
Indraneel Pole

Reputation: 299

I don't know the design and architecture of your data structure, but it seems wrong to map two completely different types to same "field". I would rather create two separate properties to keep it clean. Something like

  type ObjType = {
   field1: Field1Type;
   field2: Field2Type;
   }

Having said that if you really have to put it in one field property, What you did is more or less correct. You can also do something like following

obj.field = <Field2Type>(obj.field);

If the types are not "either or" in your use-case (Meaning they are extensions instead of exclusive types) Then you can intersect them like this -

type Field2Type = Field1Type & {
  b: string;
  c: number;
};

And then your field in obj is by default Field2Type.

type ObjType = {
   field: Field2Type
}

And then you don't need any explicit mapping. enter image description here

And result -

enter image description here

But honestly, if these two types are exclusive, it is better to have two properties. That way it is much cleaner.

Upvotes: 1

Related Questions