3

What I know

When using TypeScript with angular's ui state, I can provide "type assertion" with the UI-Router definitely typed library.

Using this, I can inject $state and have code similar to the following

function myCtrl($state: ng.ui.IStateService){
    // Some code
}

This gives me correct autocompletion/error reporting for $state's methods.

So far, this is all fine.

The problem

When I try to access a property of params like the following

function myCtrl($state: ng.ui.IStateService){
    // Trying to access a property of $state.params
    var example = $state.params.example;
}

I get an error saying:

Property 'example' does not exist on IStateParamsService

because quite rightly, TypeScript doesn't know about this property.

I considered trying:

Defining my own Interface that extends ng.ui.IStateService

interface IMyState extends ng.ui.IStateService{
    params: {
        example: string;
    };
}

Then set the type to my interface

function myCtrl($state: IMyState){
    var example = $state.params.example;
}

This gets rid of the error.

What is the correct type to use for $state?

Should I be defining my own interface like in my example?

8
  • some inspiration how could you use TS and angularJS here Commented May 23, 2016 at 10:16
  • @RadimKöhler Thanks. I am using importing/exporting classes etc. I just tried to keep it simple for the sake of this question. Useful link though. Commented May 23, 2016 at 10:19
  • Just a hint before you'll get your answer... I am using class with the static $inject notation... hint ;) Commented May 23, 2016 at 10:19
  • @RadimKöhler I use class and static $inject notation in my production code. However, I still need to annotate the parameters correctly. I just thought using it here adds unnecessary confusion. Commented May 23, 2016 at 10:25
  • If you can show me some real.. broken .. code (best in plunker) I will help you... as far as I could... Other words... snippets in your question are not clear to me.. not sure what is not working. I do use UI-Router, TS and AngularJS... so some experience could be shared Commented May 23, 2016 at 10:26

2 Answers 2

5

With Typescript, we really can easily extend a contract, coming with UI-Router .d.ts.

So this is the original definition (UI-Router d.ts. file):

// a state object
interface IStateService {
    ...
    params: IStateParamsService;
    ...
// params
interface IStateParamsService {
    [key: string]: any;
}

And we can just introduce into our custom .d.ts these lines

declare module angular.ui
{
    export interface IStateParamsService { example?: string; }
}

And that will now give us ability to consume $state and its params with example:

MyMethod($state: ng.ui.IStateService)
{
    let x = this.$state.params.example;
    ...
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I hadn't thought of this!
Great to see that, enjoy UI-Router and TS ;)
3

$state.params are of type IStateParamsService and if you look at the type signature you can read that it is an indexable type.

Indexable types have an index signature that describes the types we can use to index into the object, along with the corresponding return types when indexing.

The described type of IStateParamsService is

(key: string): any

which means something like, "you can store objects of type any(everything is an any) and read the objects by the key (or index or you-name-it, this is where the name indexable type comes from) of type string".

here some code:

// this gives us an object of type IStateParamsService
let params = $state.params;

// params is a indexable type
// we want the object stored at index 'example'
let example = params['example'];
// or
let example = $state.params['example'];

more informations about interfaces and types can be found here.

1 Comment

Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this".

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.