Some coworkers use different method to convert item in Typescript, and I was curious about which method would be the best or the most conventional.
The case is that we have 2 classes A and B with the same parent, and a list with both types. Then when I pick an item I want to access a specific child attributes.
enum Type {
A = "A",
B = "B"
}
class Parent {
type: Type
}
class A extends Parent {
a: string
}
class B extends Parent {
b: string
}
array: Parent[] = [...]
So option 1 would be to cast the parent after checking the type
getSpecificAttribute(item: Parent) {
let result = null;
switch(item.type) {
case Type.A: const child = item as A; result = child.a; break;
case Type.B: const child = item as B; result = child.b; break;
default: break;
}
return result;
}
Option 2 is new to me, using intersection as the parameter type
getSpecificAttribute(item: A & B) {
let result = null;
switch(item.type) {
case Type.A: result = item.a; break;
case Type.B: result = item.b; break;
default: break;
}
return result;
}
Or other option ?
By defining the type
property on each class, no assertion is needed:
enum Type {
A = "A",
B = "B",
}
class Parent {
constructor (readonly type: Type) {}
}
class A extends Parent {
readonly type = Type.A;
a: string;
constructor (str: string) {
super(Type.A);
this.a = str;
}
}
class B extends Parent {
readonly type = Type.B;
b: string;
constructor (str: string) {
super(Type.B);
this.b = str;
}
}
function getSpecificAttribute (item: Parent): string | null {
if (item instanceof A) return item.a;
if (item instanceof B) return item.b;
return null;
}