Bonjour,
Je commence à utiliser typescript et je fais face à un problème qui commence à me rendre fou ...
Voila, je ne comprends pas bien comment fonctionne l'assignation de type pour une promesse.
Je vous montre 2 morceaux de code
testP(): Promise<number> {
return new Promise<string>((resolve, reject) => {
resolve("string");
});
}
Ce code me renvoit bien une erreur de compilation, jusque la pas de problème.
En revanche, si je transforme mon code comme ceci
testP(): Promise<number> {
return new Promise((resolve, reject) => {
resolve("string");
});
}
La, pas de soucis, le code se compile alors que selon moi il devrait renvoyer la même erreur que précédemment.
Je me doute que je dois faire une erreur grossière, mais je bloque complètement ...
Des idées ?
Merci d'avance !
Par defaut, new Promise()
est de type Promise<any>
qui passe donc la validation.
testP(): Promise<number> {
return new Promise((resolve, reject) => { // equivalent a new Promise<any>
resolve("string");
});
}
Dans la documentation de typescript, il est indiqué ceci pour any
We may need to describe the type of variables that we do not know when we are writing an application. These values may come from dynamic content, e.g. from the user or a 3rd party library. In these cases, we want to opt-out of type-checking and let the values pass through compile-time checks
Defy: oui, le premier code renvoit une erreur ce qui est normal, je ne comprends pas pourquoi le second n'en renvoit pas.
Prbaron: Oui, le type par défaut est bien "any", mais le problème ne change pas.
Pourquoi:
testP(): Promise<number> {
return new Promise<any>((resolve, reject) => {
resolve("string");
});
}
Ne renvoit pas d'erreur.
Mais:
testP(): Promise<number> {
return new Promise<string>((resolve, reject) => {
resolve("string");
});
}
En renvoit une.
Je dois apsser à coté de quelque chose ...
Dans la documentation de typescript, il est indiqué ceci pour any
We may need to describe the type of variables that we do not know when we are writing an application. These values may come from dynamic content, e.g. from the user or a 3rd party library. In these cases, we want to opt-out of type-checking and let the values pass through compile-time checks
Cela signifie que ton type n'est pas analysé et qu'il assume que tu va bien renvoyer un number.
Ok, merci beaucoup pour ta réponse !
Mais du coup il y a quelque chose que je ne comprends pas.
J'ai fais le tuto d'angular 2: https://angular.io/docs/ts/latest/tutorial/
Et il y a une chose que je ne comprends pas.
Voila un extrait du code
import 'rxjs/add/operator/toPromise';
export class Hero {
id: number;
name: string;
}
export class HeroService {
private headers = new Headers({'Content-Type': 'application/json'});
private heroesUrl = 'app/heroes';
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data)
.catch(this.handleError);
}
}
Et maintenant, imaginons que la requette http renvoie:
[
{id: 11, name: 'Mr. Nice'},
{id: "stringId", name: 'Narco'}
]
Je m'attend à ce que mon code est un bug car un des id est un string et pas un number.
Or, rien, pas de soucis tout roule.
Pourquoi ?
Voici la définition de toPromise in rxjs
export function toPromise<T>(PromiseCtor?: typeof Promise): Promise<T> {
if (!PromiseCtor) {
if (root.Rx && root.Rx.config && root.Rx.config.Promise) {
PromiseCtor = root.Rx.config.Promise;
} else if (root.Promise) {
PromiseCtor = root.Promise;
}
}
if (!PromiseCtor) {
throw new Error('no Promise impl found');
}
return new PromiseCtor((resolve, reject) => {
let value: any;
this.subscribe((x: T) => value = x, (err: any) => reject(err), () => resolve(value));
});
}
Je pense qu'il utilise root.Promise
qui est l'implémentation de window.Promise
et tu coup on en revient à la même explication que plus haut, cela crée une Promise<any>
.
Ceci n'est qu'une déduction cependant.
PS : data est de type any
et pas de type Hero[]
.
Ok, cela confirme ce que je pensais, à savoir que le toPromise() crée une Promise<any>.
Ma question: comment faire pour que cela me déclenche une erreur si je ne recoit pas un tableux de "Hero".
Rajouter cela:
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
Ne change absolument rien.
Ps: Merci pour le temps passer à me répondre :)
Je pense qu'il faudrait plutot itérer sur ton response.json().data
pour créer un new Hero()
. Comme ça tu es sûr de ce que tu as dans ton objet.