Amin Mohamed Ajani Amin Mohamed Ajani - 8 months ago 45
TypeScript Question

Accept Array of Interfaces OR single interface in TypeScript

Really new in TypeScript. I have an array of presets that the user can add or modify existing ones. Since it has a couple of keys only, I made an interface.

interface IStylePreset {
type : string;
backgroundColor : string;
color? : string

And the implementation is here:

static stylePresets : Array<IStylePreset> = [
{ type: "default", backgroundColor: "#37474f" , color: "#ECEFF1"},
{ type: "success", backgroundColor: "#37474f", color: "#ECEFF1" },
{ type: "error", backgroundColor: "#d32f2f", color: "#EEE"}

Now I have a config function that takes a custom preset to either change existing presets or add new ones.

static config = {
types(newPresets) : void {
newPresets = [].concat(newPresets);
for(var i = 0, len = newPresets.length, current; i< len; i++){
var pos = Message.Util.find(Message.stylePresets, newPresets[i].type)
current = newPresets[i];
if(pos !== -1) for(var key in current) Message.stylePresets[pos][key] = current[key];
else Message.stylePresets[Message.stylePresets.length] = current;

The problem is, I can't figure out what to specify in the type of
since it's accepting both an array of objects and as well as a single object (which makes into a single element array
newPresets = [].concat(newPresets);

I'm trying to learn TypeScript and I don't know if what I'm doing is right. Can someone please help me out here? Further reading material or docs would be gold.


Use a TypeScript union type: IStylePreset | IStylePreset[].

In the function body you can check with Array.isArray() whether an array or a single instance was passed. Actually, in this case, concat() does already check internally whether an array or an instance is concatenated so the solution is simple:


class Config {
    private presets: IStylePreset[] = [];

    public addPresets(presetOrArray: IStylePreset | IStylePreset[]) {
        // Concat will concat either Array or instance
        this.presets = this.presets.concat(presetOrArray);

    public getPresets(): IStylePreset[] {
        return this.presets;

let config = new Config();
console.log(config.getPresets().length); // prints 4