Callum Linington
Callum Linington

Reputation: 14417

Typescript multiple type definition

I have defined the interface in a d.ts file:

declare module myModule
{
    interface IQedModel {
        field: string | string[];
        operator: string;

    }
}

In an anuglar controller I have implemented it:

vm.filters = <myModule.IQedModel>{
    operator: 'and',
    field: []
};

function populateFields() {
    vm.filters.field = [];

    angular.forEach(addedFilters, item => {
        vm.filters.field.push(item.data); //<-- THIS LINE SHOWS ERRORS
    });
}

The error is:

Property 'push' does not exist on type 'string | string[]'

What is the issue here?

Upvotes: 2

Views: 4922

Answers (2)

Remo H. Jansen
Remo H. Jansen

Reputation: 24979

You can use generics:

declare module myModule
{
    interface IQedModel<T> {
        field: T;
        operator: string;

    }
}

var filters = <myModule.IQedModel<Array<string>>>{
    operator: 'and',
    field: []
};

var filters2 = <myModule.IQedModel<string>>{
    operator: 'and',
    field: ""
};

filters.field.push(""); // works
// filters.field = "" // String not assignable to string[]


filters2.field = ""; // works
// filters2.field.push(""); // push does not exist on type string

Or:

declare module myModule
{
    interface IQedModel<T> {
        field: T;
        operator: string;

    }

    interface ISingleFieldQedModel extends IQedModel<string> {}
    interface IMultiFieldQedModel extends IQedModel<string[]> {}
}

var filters = <myModule.IMultiFieldQedModel>{
    operator: 'and',
    field: []
};

filters.field.push("");
// filters.field = "" // String not assignable to string[]


var filters2 = <myModule.ISingleFieldQedModel>{
    operator: 'and',
    field: ""
};

filters2.field = "";
// filters2.field.push(""); // push does not exist on type string

You can also use Type Guards, take a look to this but there are some issues at the moment.

Upvotes: 2

Callum Linington
Callum Linington

Reputation: 14417

So based on BGR comments I need to cast to an array first:

(<string[]>vm.filters.field).push(item.data);

Upvotes: 1

Related Questions