Join me on this journey as we delve into subtypes and base types in Typescript:
In Typescript, a type with more properties should be assignable to a base type where a subset of the properties is expected. This means that a source object with additional properties can be assigned to a target object expecting only a subset of those properties:
let source = { a1: 0, a2: 0}
let target: { a1: number } = source
Interestingly, due to structural typing, Partial<A>
is considered a subtype of Partial<B>
, and vice versa. Missing optional properties do not disqualify a type from being a subtype, as an empty object {}
can serve as the base type for any other type. The compiler confirms this through conditional types:
type q1 = Partial<A> extends Partial<B> ? "Y" : "N" // Y
type q2 = Partial<B> extends Partial<A> ? "Y" : "N" // Y
There is one exception to this rule, which is excess property checks when assigning object literals directly to a specific type reference. This check prevents errors caused by unintentional extra or misspelled properties:
let target: { a1: number } = { a1: 0, a2: 0} // err
The purpose of excess property checks is to catch common mistakes in object literal assignments. However, these checks do not apply to indirect assignments like
let partialA: Partial<A> = b;
.
Another complexity arises from the concept of weak types, such as Partial<A>
. These types have only optional properties and are non-empty. Any object can be assigned to a weak type since they do not demand mandatory properties:
let k = { foo: 0 }
let partialA: Partial<A> = k;
Despite k
having no common properties with Partial<A>
, it remains assignable because weak types require no specific properties. The introduction of the weak type detection rule enforces constraints on assigning completely unrelated types to weak types.
In your scenario, both Partial<A>
and Partial<B>
share the property x1
, allowing for their inter-assignability without triggering enforcement of the weak type detection rule. As long as there are common properties present, the assignment between subtypes is generally permitted.