If you look at the signature of the Observable:
export declare class Observable<T> implements Subscribable<T> {...}
you can see that it requires argument T
. SomeThing<SomeType>
is called a generic and to quote TypeScript Hadnbook, if you look at generic identity function:
function identity(arg: any): any {
return arg;
}
While using any is certainly generic in that will accept any and all types for the type of arg, we actually are losing the information about what that type was when the function returns. If we passed in a number, the only information we have is that any type could be returned.
Instead, we need a way of capturing the type of the argument in such a way that we can also use it to denote what is being returned. Here, we will use a type variable, a special kind of variable that works on types rather than values.
function identity<T>(arg: T): T {
return arg;
}
You can define getTeachers(): any {}
in case you don't care about what this function returns (or if you don't know). It will work, but suppose few months from now you are upgrading your app, you make a nice shinny new component and it needs to call getTeachers()
. What will it return? Any. Cool. =digs-through-months-old-code= Repeat N times (;
But since you know what function does (returns http.method, which is an Observable) you can write getTeachers(): Observable<any>{}
. ...shinny new component; call getTeachers()
. What will it return? Observable. Nice, I can subscribe to it, and get Any. OK, I can work with that...
In most cases/examples , that's enough. But you can be even more specific.
If you know what this.http.get('someUrl')
returns (let's say it's an JSON object in the body of the response, with header 'Content-Type' set to 'application/json' - and you use Respone.json() to extract it), you can write getTeachers(): Observable<{}>{}
. Now we know it's an Object.
Finally, if you know that object will have same properties as interface Teacher, you can define your function like this:
getTeachers(): Observable<Teacher> {}
Why is there no cast-syntax to convert the generic any type of res.json() to the more specific type Teacher?
There's no conversion here, data stays the same. You are just providing "description" of that data by declaring it to be of specific type. Based on the information you know about it. No magic (:.
Why is it recommended for Teacher to be a TypeScript interface and not a TypeScript class?
In this context Teacher
can be either class or an interface. Here it doesn't matter, TypeScript will read information from either class or interface. If you won't use Teacher in any other context you make an interface (it doesn't compile to JavaScript, so less code). If you use it somewhere else, for example if you need an instance of Teacher
:
let new_guy = new Teacher();
then you should declare Teacher as a class.