Search code examples
javascriptangularjstypescriptangular-ui-routerangular-ui

Angular ui-state with params type in typescript


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?


Solution

  • 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;
        ...