问题
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?
回答1:
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;
...
回答2:
$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.
来源:https://stackoverflow.com/questions/37387832/angular-ui-state-with-params-type-in-typescript