Is it possible to have superclasses/interfaces and subclasses/implementations that depict the typing in an abstract way?

Lets say you have types and following functions:

```
class Animal {
  name: string;
}
class Bird extends Animal {
  canFly: boolean
}
class Dog extends Animal {
  tailLength: number;
}

enum animals {
  bird = 'bird',
  dog = 'dog'
}

class AnimalDTO {
  type: animals;
  information: Animal;
}

function registerAnimal(animalDto: AnimalDTO) {
  if (animalDto.type == animals.dog) {
    petDog(animalDto.information);
  }
}

function petDog(dog: Dog) {
  console.log(`Petting ${dog.name} with tail length ${dog.tailLength}`)
}

```

Now in the registerAnimal function it complains

```
Argument of type 'Animal' is not assignable to parameter of type 'Dog'.
  Property 'tailLength' is missing in type 'Animal' but required in type 'Dog'.

```

How can I have a function that accepts this global DTO and I can apply logic to, based on the passed type, project the passed information to the specific subclass?