Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 954
Matt Lishman Avatar asked Jul 01 '26 09:07

Matt Lishman


2 Answers

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;
    ...
like image 196
Radim Köhler Avatar answered Jul 03 '26 22:07

Radim Köhler


$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.

like image 29
Lusk116 Avatar answered Jul 03 '26 23:07

Lusk116