2

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?

4
  • The compiler cannot infer the type.You should cast to the array: (vm.filters.field as string[]).push(...) Commented Oct 29, 2015 at 11:24
  • @BGR is that not what the line at the top of the function does? Commented Oct 29, 2015 at 11:27
  • Obvioussly the compiler is falling back to the type definition: if you remove the cast to <myModule.IQedModel> on the assignment to vm.filters the compiler will infer the array and will not complain. (the assignment within the populateFields function is unnecessary) Commented Oct 29, 2015 at 11:38
  • Okay cool, I was migrating a JS file to TS so that's why it is there, I guess I'm going to run into a lot of relics Commented Oct 29, 2015 at 11:48

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I like that, neat stuff!
1

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.