Change type of an object's property based on another property's value in class variable

TL;DR TypeScript type inference fails in class when using union types

I’ve ran into an issue with typescript when dealing with classes and union types.

This is a basic version of the types that i’ve got:

type CommonData = {
    name: string

type Dog = {
    age: number
} & CommonData

type Bat = {
    wingspan: number
} & CommonData

type Animal = {
    type: "dog"
    data: Dog
} | {
    type: "bat"
    data: Bat

The Animal type changes its data type based on the value of the type field.

So, when creating objects using the Animal type, typescript is able to determine what type of data is used for each animal based on the type field. Example below:

const bat: Animal = {
    type: "bat",
    data: {
        name: "tim",
        wingspan: 9000

// has type inference,

However, when implementing the same type in a class, typescript doesn’t recognize what type of data is returned. Here’s an example of what my current code is like:

class AnimalClass {
    animal: Animal

    constructor (animal: Animal) {
        this.animal = animal

const dog = new AnimalClass({
    type: "dog",
    data: {
        name: "bob",
        age: 10

// no type inference on data, typescript doesn't know that it's a Dog has a type of Dog | Bat. Is it possible to alter the code to infer that the type of is Dog

Thanks in advance 🙂

Here’s the full code: Typescript Playground

>Solution :

You can use a generic annotaion on the Animal class as the following, to make the inference complete:

class AnimalClass<T extends Animal> {
    animal: T;

    constructor (animal: T) {
        this.animal = animal


Leave a Reply