microsoft / microsoft/TypeScript
Object literals should have a `this` type too
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 1 j 19 h
- PR mergées (30 j)
- 117
Description
TypeScript Version: 3.7.0-dev.20190831
Search Terms: this return type object composing composition
Code
I tried writing some self-contained parts of objects as a kind of multiple-inheritance or object composition, which I would combine later, and ran into this case.
const a = {
Clone() {
return this;
},
x: 1,
};
const b = {
Clone: a.Clone,
y: 2,
};
console.log(b.Clone().x); // number, bad! Should be an error!
console.log(b.Clone().y); // compiler error, bad! This should be acceptable!
Expected behavior: this, the return type of Clone, should evaluate to typeof b in b.Clone()
Actual behavior: It evaluates to typeof a, since it was defined in a
This can be circumvented by defining this as a type parameter like so:
const a = {
Clone<T>(this: T) {
return this;
},
x: 1,
}
const b = {
Clone: a.Clone,
y: 2
};
console.log(b.Clone().x); // compiler error, good!
console.log(b.Clone().y); // works! Also good!
Another interesting problem at play here though, is that using a type parameter for this also means that TS doesn't know what could be inside of this. This means you have to manually specify whatever members you hope to have access to. It would be nice if you could do T extends typeof a and it would automatically drop all the members of a in there. Right now, it will error if you do this:
'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)
I think all methods like this should, therefore, be implicitly equivalent to the following:
const a = {
Clone<T extends typeof a>(this: T) {
console.log(this.x); // should work
return this;
},
x: 1,
}
Then, b.Clone() would error since b is not a superset of a. Unless you did c = Object.assign({}, a, b), and did c.Clone()
Related Issues: https://github.com/microsoft/TypeScript/issues/29122
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par l’exemple TypeScript Playground lié et comparez le type de retour inféré de Clone lorsqu’il est copié de a vers b. Consultez l’issue associée #29122 pour le contexte de ce comportement. Le travail est terminé lorsqu’il est déterminé et implémenté si les méthodes des littéraux d’objet doivent inférer this à partir de l’utilisation de leur objet conteneur, tout en préservant l’accès valide aux membres de l’objet d’origine.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- typescript
- Domaine
- compilers
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 30/100