This class holds either a single Item or an array of items Item[], determined by a setting at runtime (this.config.isMultiple).
How can I narrow down the class' generic type with a type guard to Item[] in the whole if (this.isMultiple)-Block? (which has many, many more accesses than this example, each needing to have an individual typecast, otherwise).
Minimum working example:
interface Item { /* ... */ }
class Demo <DATATYPE extends Item | Item[]> {
config: { isMultiple: boolean; }
value: DATATYPE;
get isMultiple(): boolean {
return this.config.isMultiple;
}
addValue(value: Item) {
if (this.isMultiple) {
if (!Array.isArray(this.value)) {
this.value = [] as Item[];
// TS2322: Type 'Item[]' is not assignable to type 'DATATYPE'. 'Item[]' is assignable to the constraint of type 'DATATYPE', but 'DATATYPE' could be instantiated with a different subtype of constraint 'Item | Item[]'.
}
this.value.push(value);
// TS2339: Property 'push' does not exist on type 'Item | Item[]'. Property 'push' does not exist on type 'Item'.
} else {
this.value = value;
// TS2322: Type 'Item' is not assignable to type 'DATATYPE'. 'Item' is assignable to the constraint of type 'DATATYPE', but 'DATATYPE' could be instantiated with a different subtype of constraint 'Item | Item[]'.
}
}
}