microsoft / microsoft/TypeScript
Proposal: Easier Migration with Loose Mode in TypeScript Files
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.4k
- Merge moyen
- 1 j 19 h
- PR mergées (30 j)
- 117
Description
This issue is the dual of #23906.
Background
TypeScript has always aimed at making migration from JavaScript as easy as possible; however, even today there exists a bit of an awkward gap where you must rewrite your JavaScript code to put it in a state where it's "ready" to be converted to TypeScript. As an example, users might start annotating their code with JSDoc to get better analysis in .js files, but once they switch their file extensions to .ts, TypeScript pretends like it doesn't understand those annotations anymore.
Proposal
TypeScript can provide a new "loose" mode (which we'll refer to as looseTs). This loose mode can be seen as a hybrid between the allowJs/Salsa language service support for JavaScript, along with TypeScript itself.
Let's explore what would this experience would look like.
Special JavaScript Declarations Are Allowed
TypeScript would understand certain constructs that are currently special cased in JS files. For example, the following construct would create what TypeScript effectively sees as a constructor.
function Foo() {
this.x = 10;
this.y = 20;
this.z = 30;
}
new Foo().x + new Foo().y + new Foo().z // all well-typed as 'number'
Our language service could provide tooling to help refactor this to a more canonical sort of class.
Type Annotations & Declarations
All TypeScript constructs would continue to work, but so would JSDoc annotations & declarations.
/**
* @typedef {PersonName} string
*/
export interface Person {
// valid to reference JSDoc declarations in the same file
name: PersonName;
}
TypeScript constructs would always take precedent over their JSDoc counterparts when they potentially conflict. For example, the following provides an error at worst, but will always consider x to be a string:
/**
* @type {number}
*/
var x: string;
Class Properties
Today, TypeScript requires all classes to have property declarations.
Future versions of ECMAScript might allow property declarations.
The story here is: pick one. If classes contain no property declarations, then we'll fall back to Salsa-style inference from the constructor body. If any property declarations are present, then any access to this with a member that hasn't been declared is an error.
// Good!
class AllDeclared {
a: number;
constructor() {
this.a = 0;
}
}
// Good!
// Also, users get a quick fix.
class OnlyInitialized {
constructor() {
this.a = 0;
}
}
// Bad!
class MixedDeclarationsAndInitialization {
a: number;
constructor() {
this.a = 10;
this.b = "hallo";
}
}
We can provide tooling to help migrate users to TypeScript code that declares all of the initialized properties.
Best-Effort Completions
Like in Salsa, we should provide loose completions for things like any by default. This might be editor-configurable, but see #5334 for some more discussion.
More?
Your ideas here!
Drawbacks
One argument is that this could potentially dilute the value of the language, similar to concerns around // @ts-ignore.
Another related argument has to do with cognitive overhead. Our heuristics around understanding JavaScript constructs in Salsa (our JS language service) feels somewhat opaque. While we can document what special constructs we support, TypeScript's current model is significantly simpler. It might not be clear what features "proper TypeScript" actually supports (i.e. what exactly are you giving up when you turn off looseTs?)
Alternatives
We may want to consider alternatives before we commit to something like this.
Type Annotations in JavaScript Files
This proposal has proposed the idea of understanding Salsa/JS constructs in .ts files, but one could approach it from the other direction: Salsa could support type annotations in .js files instead under a specific mode. Our main concern here has been the conflation between what is possible in JavaScript today, and what constructs are specific to TypeScript. Additionally, providing non-standard constructs in .js files might give users the wrong impression over what we're trying to achieve (to clarify, in this issue, we're here to provide tooling for JavaScript users and make it easier to migrate to TypeScript).
Tooling Tooling Tooling Tooling
Now that we have suggestion diagnostics, we can potentially provide suggestions & tooling to just fix "legacy" JS constructs in the language service once you've moved to TypeScript. The counter-point here is that users will still likely experience the "sea of red" problem when you first switch a file over to .ts.
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
Aucun fichier d’implémentation, test ou point d’entrée n’est nommé. Commencez par lire le dual issue #23906 et la discussion associée #5334, puis déterminez si le comportement looseTs proposé a un périmètre convenu ; l’issue ne définit pas de critères d’acceptation concrets ni ce qui permet de considérer le travail comme terminé.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript, typescript
- Domaine
- compilers
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- À clarifier
- Accessibilité débutants
- 25/100