I want to create a hierarchy of Typescript interfaces because I think classes would be an overkill in my case. The main obstacle is checking if an object has a specific type. I solved it this way:
enum AnimalId {
Mammal = 1,
Fish = 3,
}
interface BaseAnimal {
id: number
categoryId: AnimalId
name: string
}
interface Fish extends BaseAnimal {
categoryId: AnimalId.Fish
fins: number
}
interface Mammal extends BaseAnimal {
categoryId: AnimalId.Mammal
speed: number
}
type Animal = Fish | Mammal
const fish1: Fish = {
id: 1,
categoryId: AnimalId.Fish,
name: 'trout',
fins: 5,
}
const fish2: Fish = {
id: 2,
categoryId: AnimalId.Fish,
name: 'salmon',
fins: 8,
}
const mammal1: Mammal = {
id: 3,
categoryId: AnimalId.Mammal,
name: 'lion',
speed: 80,
}
const animals: Animal[] = [fish1, fish2, mammal1]
/* eslint-disable no-case-declarations */
for (const animal of animals) {
let score = 0
switch (animal.categoryId) {
case AnimalId.Fish:
score += animal.fins
break
case AnimalId.Mammal:
score += animal.speed
break
default:
break
}
}
There are two things I don't like with the current approach:
I have to create a Union type
Animal
with all specific Animal types. I would rather just use BaseAnimal instead.If I want to create a new specific Animal e.g. of type
Fish
I also have to setcategoryId: AnimalId.Fish
. It would be great if this is done implicitly:
const fish2: Fish = {
id: 2,
name: 'salmon',
fins: 8,
}