arraystypescripttypesconditional-statementstype-declaration

Is there a way to put multiple types of data in an array in TypeScript?


Here's an example of what I'm asking.
Say that we have two interfaces, Cats and Dogs. How can I make an array that can hold both Cats and Dogs?

interface Cats {
  name: string;
  age: number;
}

interface Dog {
  owner: string;
}

const cat1: Cats = {
  name: "Jimmy",
  age: 5,
}

const dog1: Dogs = {
  owner: "Bobby",
}

// The line below doesn't work how I think it would work
const animalsList: Array<Cats> | Array<Dogs> = [cat1, dog1];

The variable animalsList should be able to have both Cats and Dogs in it, but I am getting errors like
"Type Dogs can not be assigned to type Array<Cats>"


Solution

  • Here is a full sample:

    // Welcome to the TypeScript Playground, this is a website
    // which gives you a chance to write, share and learn TypeScript.
    
    // You could think of it in three ways:
    //
    //  - A place to learn TypeScript in a place where nothing can break
    //  - A place to experiment with TypeScript syntax, and share the URLs with others
    //  - A sandbox to experiment with different compiler features of TypeScript
    
    const anExampleVariable = "Hello World"
    console.log(anExampleVariable)
    
    // To learn more about the language, click above in "Examples" or "What's New".
    // Otherwise, get started by removing these comments and the world is your playground.
      
    class Cats {
        private name: String;
        constructor(name: String) {
            this.name = name;
        }
        public dump() { console.log(`I am cat ${this.name}`); }
    }
    class Dogs {
        private name: String;
        constructor(name: String) {
            this.name = name;
        }
        public dump() { console.log(`I am dog ${this.name}`); }
    }
    
    class Test {
        public animalsList : Array<Cats> | Array<Dogs> = Array();
    }
    
    const t = new Test();
    t.animalsList = Array(new Cats('cat1'), new Cats('cat2'));
    t.animalsList.forEach((v, i) => { v.dump(); });
    
    t.animalsList = Array(new Dogs('pluto'), new Dogs('goofy'));
    t.animalsList.forEach((v, i) => { v.dump(); });
    
    // The following line fails
    //t.animalsList = Array(new Dogs('pluto'), new Cats('cat2'));
    //t.animalsList.forEach((v, i) => { v.dump(); });
    

    You can try it on https://www.typescriptlang.org/play