Typescript: Prise en charge des plugins pour les transformateurs personnalisés

Créé le 2 mars 2017  ·  99Commentaires  ·  Source: microsoft/TypeScript

Depuis que #13764 a atterri, il est facile d'écrire des transformateurs personnalisés. Cependant, si je comprends bien l'API, il est nécessaire de dupliquer toute la ligne de commande tsc juste pour ajouter un seul transformateur. Cela conduit à des incompatibilités car ces applications, selon le type de script, ne prennent pas en charge les mêmes fonctionnalités que l'outil de ligne de commande tsc.

Il serait donc préférable d'avoir un système de plug-in permettant de charger des transformateurs personnalisés à partir de modules de nœuds tiers, comme c'est le cas pour les proxys de service de langage #12231. Ces transformateurs s'intègrent ensuite facilement dans les outils de build/workflows de build existants.

Si quelqu'un d'expérimenté a des idées sur la façon de mettre en œuvre les changements, je suis prêt à créer un PR car cela simplifierait énormément mon projet.

Docs

Commentaire le plus utile

Je ne veux pas avoir une API de plugin exposée. Au lieu de cela, je préférerais enregistrer mes transformations personnalisées en les spécifiant simplement dans tsconfig.json au lieu d'avoir à utiliser l'API TS-Compiler. Parce que l'utilisation de l'API TS-Compiler implique que je ne peux plus utiliser l'outil de ligne de commande tsc, ce qui peut en outre impliquer qu'il ne s'intègre plus correctement dans les outils de construction et les flux de travail existants.

Tous les 99 commentaires

Nous ne prévoyons pas d'exposer le système de plug-in du compilateur à court terme. Les transformations sont exposées dans le cadre de l'API publique comme vous l'avez noté, et nous sommes en train d'écrire de la documentation et des exemples pour celles-ci.

Je ne veux pas avoir une API de plugin exposée. Au lieu de cela, je préférerais enregistrer mes transformations personnalisées en les spécifiant simplement dans tsconfig.json au lieu d'avoir à utiliser l'API TS-Compiler. Parce que l'utilisation de l'API TS-Compiler implique que je ne peux plus utiliser l'outil de ligne de commande tsc, ce qui peut en outre impliquer qu'il ne s'intègre plus correctement dans les outils de construction et les flux de travail existants.

quelque chose de nouveau à propos de la documentation et des échantillons ? @mhegazy

@MichaReiser , vous pouvez écrire un compilateur simple basé sur l'API (exemple ici ). En fait, nous utilisons très largement TS au sein de Yahoo Finance et l'API publique du transformateur a été géniale.

Voici quelques-uns des transformateurs que nous avons écrits après qu'ils soient devenus publics :
https://github.com/longlho/ts-transform-system-import
https://github.com/longlho/ts-transform-img
https://github.com/longlho/ts-transform-react-intl
https://github.com/longlho/ts-transform-css-modules-transform

@mhegazy lmk si vous avez besoin d'aide pour documenter/collecter des échantillons

@longlho
Merci pour votre échantillon.

C'est ce que je fais actuellement. Cependant, cela rend impossible l'utilisation d'autres outils de construction créés pour le tapuscrit, par exemple les chargeurs de packs Web, les chargeurs de blagues. De plus, comment puis-je utiliser l'un de vos plugins avec l'un des miens lorsque chacun de nous utilise une interface différente ?

Par conséquent, je pense que l'approche actuelle est un bon début mais pas suffisant pour un écosystème de plugins. Parce que l'utilisation d'un plugin représente trop d'efforts pour l'utilisateur et nécessite plus que la simple écriture du code de transformation pour l'auteur.

Je crois qu'un système de plugin comme celui de Babel est essentiel pour le tapuscrit si l'objectif est d'encourager la communauté à créer et à utiliser des transformateurs personnalisés.

@MichaReiser oui . Je ne dis pas que c'est suffisant pour l'écosystème, juste assez bon pour le 1er pas vers celui-ci.

J'aimerais ajouter la prise en charge des transformations dans gulp-typescript, mais je veux éviter que tous les plugins TypeScript (pour gulp, webpack, etc.) proposent une API différente. Et TypeScript pourrait même ajouter une manière différente de configurer cela plus tard. Prévoyez-vous actuellement d'ajouter cela dans un avenir proche ou lointain ?

Salut à tous, j'essaie d'écrire un préprocesseur, mais rien ne sort :[

En fait, j'ai deux questions :

  • Comment créer un fragment AST à partir d'une chaîne ?
  • Comment ajouter l'importation ?
// 1. Input
class Foo {
    templateString = 'some value';
}

// 2. After transformation
import __LIB__ from '@external/lib';

class Foo {
    templateString = (function compiledTemplate(deps) {
        // ...
        return result;
    })({lib: __LIB__});
}

// 3. Expected result
var lib_1 = require("@external/lib");
var Foo = (function () {
    function Foo() {
        this.templateString = (function compiledTemplate(deps) {
            // ...
            return result;
        })({ lib: lib_1 }); 
    }
    return Foo;
}());

Un exemple simplifié : https://github.com/RubaXa/typescript-api-questions/tree/master/import-add

⬆️ ⬆️ ⬆️
@longlho , @mhegazy Pouvez-vous donner un indice ?

@RubaXa Depuis que vous avez ajouté la déclaration d'importation dans une transformation, elle n'est pas liée ni vérifiée. Puisqu'il n'a pas été lié ou vérifié, nous ne pouvons pas résoudre __LIB__ dans votre expression en __LIB__ dans la déclaration.

Une option consiste à utiliser une importation d'espace de noms au lieu d'une importation par défaut, de sorte que votre émission ressemble à :

import * as __LIB__ from "@external/lib"

Comme il n'y a pas d'aliasing qui peut se produire.

L'autre conserve un identifiant généré pour la déclaration d'importation, selon le zip ci-joint

@RubaXa si votre objectif est de transmettre l'intégralité de l'objet module, vous souhaitez probablement utiliser la syntaxe import * as __LIB__ from "@external/lib" (qui ne nécessite pas d'aliasing) et non import __LIB__ from "@external/lib" car ce dernier importe le default export plutôt que l'intégralité de l'objet module.

oui, nous faisons également import * as foo dans notre transformateur de modules CSS pour éviter l'aliasing. Bien qu'il serait bon de puiser dans cela pour intégrer certaines exportations nommées

@rbuckton O, merci beaucoup !
Toujours intéressé par la création d'un fragment AST arbitraire à partir d'une chaîne ?

function createFragmentFromString(code: string) {
  // ????
}

function visitPropertyDeclaration(node) {
    if (ts.isIdentifier(node.name) && node.name.text === "templateString") {
        // ...
        return ts.updateProperty(
            node,
            ts.visitNodes(node.decorators, visitor),
            ts.visitNodes(node.modifiers, visitor),
            ts.visitNode(node.name, visitor),
            ts.visitNode(node.type, visitor),
            createFragmentFromString('(function compiledTemplate() { /* ... */ })()')
        );
    }
    return node;
}

C'est ce que j'espérais que le support du transformateur et le flux de travail se comporteraient comme dans TypeScript.

https://www.dartlang.org/tools/pub/transformers

Je suis également très intéressé par cette fonctionnalité.

comme @MichaReiser l'a mentionné
If someone experienced has inputs on how to implement the changes, I'm willing to create a PR as it would simplify my project tremendously.

J'adore voir les contributions des experts/du compilateur dactylographié DEV.

On dirait que quelqu'un a enveloppé le texte dactylographié pour exposer cette fonctionnalité. https://github.com/cevek/ttypescript

On dirait aussi que ts-loader l'a : https://www.npmjs.com/package/ts-loader#getcustomtransformers -----before-transformerfactory--after-transformerfactory----

Je pense que c'est quelque chose qui pourrait atterrir dans la version 2.8 de Typescript ou au moins dans la feuille de route à un moment donné, @ahejlsberg @mhegazy @DanielRosenwasser qu'en pensez-vous ? De cette façon, les transformateurs personnalisés pourraient être plus populaires et donc plus puissants. Avoir la possibilité de se connecter à transfromer du point de vue de tsconfig.json simplifierait beaucoup la vie.

Nous n'avons pas l'intention d'exposer des plugins à court terme, comme indiqué précédemment.

@mhegazy Est-ce une décision réfléchie ou est-ce hors de portée simplement en raison du faible intérêt de la communauté ?

Je n'ai pas dit ça. nous aimerions maintenir un petit coût d'API publique / de maintenabilité ainsi qu'une flexibilité pour changer la façon dont la construction est conduite à l'avenir, et ces deux éléments sont affectés par un modèle de plugin.

S'il vous plaît, arrêtez la fragmentation de l'api du plug-in de transformateur. Stabilisez l'api du plugin au-dessus de l'api du transfomer et exposez-les dans tsconfig.json.

ts-loader , parcel-plugin-typescript , rollup-plugin-typescript2 , ts-transformer-keys , ttypescript et autres.

Chacun d'eux fournit une méthode d'enregistrement de plug-in personnalisée et un format de point d'entrée de plug-in personnalisé. C'est un moyen de ts plug-in d'enfer.

Désormais, cevec/ttypescript prend en charge tous les formats de plug-in de transformateur courants. Il s'agit d'un wrapper intégré au-dessus de tous les modules dactylographiés et des commandes tsc, tsserver (juste un petit correctif ts.createProgram d'exécution). Webpack ts-loader et rollup-plugin-typescript2 peuvent être facilement configurés avec ttypescript.

TTypescript suggère un format de plug-in de transformateur universel, mais les transformateurs existants sont également pris en charge.

{
    "compilerOptions": {
        "plugins": [
            { "transform": "ts-transform-graphql-tag" },
            { "transform": "ts-transform-css-modules", "type": "config" },
            { "transform": "ts-nameof", "type": "raw", "after": true}
            { "transform": "./transformers/my-transformer.ts", "someOption1": 123, "someOption2": 321  }
        ]
    },
    "exclude": ["node_modules", "transformers/**/*"]
}

Des news sur celui-ci ? Il me semble que les auteurs TypeScript ne veulent en quelque sorte pas autoriser les transformateurs personnalisés sur vanilla TypeScript - c'est dommage, ce serait une fonctionnalité géniale.

ils ne veulent pas qu'une autre API/surface soit maintenue de peur d'avoir des difficultés à casser des éléments internes. Ironiquement, toutes ces solutions de plugins tierces sont, parce qu'il n'y a pas de standard par l'équipe ts, toutes quelque peu différentes et finiront par casser.

ils ne veulent pas qu'une autre API/surface soit maintenue de peur d'avoir des difficultés à casser des éléments internes.

Après 3 ans à travailler avec le tapuscrit et à observer son évolution, je suis arrivé à une conclusion simple. Microsoft a Open Source Typescript dans le sens du _code_, mais pas dans le sens du _process_. Dans la majorité des cas, les projets open source sont plus ou moins axés sur la communauté, tant dans les décisions que dans le codage , et cela devrait être la voie naturelle pour évoluer. Vous souvenez-vous du fork IO.js de node.js ? La communauté s'est rendu compte que les intérêts de l'entreprise n'étaient pas tellement alignés sur le modèle de gouvernance open source commun, et ils ont tout simplement bifurqué. J'espère que cela n'arrivera pas pour TypeScript, mais Microsoft devrait prendre en compte cette possibilité.
Pour être clair, je ne blâme pas les développeurs, de toute façon, ils font un excellent travail, vraiment.
Juste mon 2c, désolé pour l'OT.

Microsoft a Open Source Typescript dans le sens du code, mais pas dans le sens du processus.

Je suis totalement en désaccord avec cela. Je n'ai jamais travaillé pour Microsoft, mais j'ai eu une influence directe sur plusieurs fonctionnalités de TypeScript au cours des 4 dernières années. Je représentais une bibliothèque open source construite en TypeScript, et nous nous sommes arrangés pour avoir des conversations directes, mais tout le "débat" de toutes les fonctionnalités s'est fait en public, ici. L'équipe principale publie ses notes de réunion de conception. Le seul "initié" que j'ai eu, représentant une bibliothèque open source, a été l'occasion de défendre mon cas pour certaines fonctionnalités en personne et de rencontrer l'équipe principale. Cela m'a fait réaliser que l'équipe agit en équipe. Une caractéristique dont nous avons parlé, Anders a essentiellement dit que le problème était trop difficile et qu'il faudrait beaucoup de temps pour le résoudre et résoudre les "vrais" problèmes auxquels les gens étaient confrontés. C'était il y a deux ans et dans TypeScript 3.0, nous l'avons enfin compris. Mais la communauté a une voix dans le processus de conception, mais comme toute communauté, nous avons des voix factices et diverses, et aucune équipe ne pourrait plaire à tout le monde, et si c'était le cas, TypeScript serait un _vraiment_ mauvais outil.

Vous souhaitez également étiqueter l'équipe principale "Microsoft". L'équipe de base était la moindre équipe Microsoft que j'aie jamais rencontrée. Ils se sont battus pour obtenir le contrôle total de leur cadence de publication, après avoir été fondés sur le contrôle total de leur contenu de publication. Ils se sont également battus pour l'ouverture et la transparence. Ils se sont battus pour migrer vers GitHub depuis CodePlex. Certes, ils ne sont plus si uniques chez Microsoft car plusieurs autres équipes ont adopté leur modèle, mais ce sont, à ma connaissance, ceux qui ont tout lancé, suivis rapidement par l'équipe VSCode.

Donc, ce n'est pas parce que l'équipe principale sélectionne et choisit ses batailles, s'en tient à ses principes de conception que la communauté n'a pas de voix, mais en tant que voix, nous souffrons d'un trouble psychotique de la personnalité multiple. Nous sommes un client difficile à servir.

Ma compréhension est que c'est la même chose que # 16607, ou cela permettrait-il d'atteindre un objectif différent ? En tant qu'auteur de plugin très récent moi-même, j'aimerais aussi voir cela exposé - y compris lorsque je travaille avec TypeScript à l'aide du plugin Babel.

@mrmckeb , ce problème concerne la normalisation et l'exposition de la transformation AST dactylographiée, qui existe déjà, tandis que le problème lié semble discuter de la transformation de fichiers entiers dans une portée très large (indéfinie).

Je veux ajouter mes 2 cents ici. Certains d'entre vous ont peut-être entendu parler du brillant projet babel-plugin-macros . Fondamentalement, au lieu d'avoir des milliers de plugins Babel différents, il peut y avoir le seul qui est ensuite alimenté par un code utilisateur pour effectuer une transformation. Un système incroyablement transparent sans avoir besoin de jouer avec la configuration tout le temps. Ceci est particulièrement intéressant pour des projets comme CRA qui prend en charge les macros mais interdit une configuration supplémentaire.

Aujourd'hui, j'ai ouvert la discussion sur la manière d'obtenir cela dans le monde TypeScript. Si vous avez des idées, n'hésitez pas à venir partager.

En fin de compte, j'espère que si nous réussissons d'une manière ou d'une autre, cela ne sera pas nécessaire car une seule transformation sera nécessaire.

@FredyC c'est un projet sympa, mais nous aurions besoin que ce problème soit résolu afin d'injecter facilement quelque chose comme ça dans le compilateur en utilisant uniquement tsc . Par exemple, avec babel-plugin-macros, il doit toujours être spécifié dans .babelrc et ce serait bien de spécifier quelque chose comme ça dans le typescript dans tsconfig.json .

En fait, suggérez-vous qu'il serait bien d'avoir un comportement de type babel-plugin-macro intégré à TypeScript et qu'aucune configuration ne serait nécessaire? Cela pourrait être sympa, mais personnellement, je préférerais une solution configurable qui permet de spécifier des transformateurs personnalisés dans tsconfig.json , puis une version de babel-plugin-macros qui prend en charge les nœuds ast tapuscrits pourrait être spécifiée.

@dsherret Oui, je ne m'attends pas à ce que cela fasse partie de TypeScript lui-même. Cependant, je peux imaginer qu'une fois la transformation prête, il pourrait être facile de préparer un minuscule wrapper de type tsc qui n'injecterait que cette transformation pour les macros et le reste pourrait être fait à partir d'un code utilisateur.

Edit: En fait, le petit wrapper est déjà là, avec https://github.com/cevek/ttypescript mentionné ci-dessus, il serait facile d'instruire de l'utiliser avec le plugin de macros universel et c'est gagnant-gagnant.

J'ai juste besoin de trouver des personnes qui connaissent bien les transformations Typescript pour comprendre un prototype de base. Je peux discuter et parler, mais sa mise en œuvre dépasse mes compétences actuelles.

ils ne veulent pas qu'une autre API/surface soit maintenue de peur d'avoir des difficultés à casser des éléments internes.

Après 3 ans à travailler avec le tapuscrit et à observer son évolution, je suis arrivé à une conclusion simple. Microsoft a Open Source Typescript dans le sens du _code_, mais pas dans le sens du _process_. Dans la majorité des cas, les projets open source sont plus ou moins axés sur la communauté à la fois dans les _décisions_ et dans le _codage_, et cela devrait être la manière naturelle d'évoluer. Vous souvenez-vous du fork IO.js de node.js ? La communauté s'est rendu compte que les intérêts de l'entreprise n'étaient pas tellement alignés sur le modèle de gouvernance open source commun, et ils ont tout simplement bifurqué. J'espère que cela n'arrivera pas pour TypeScript, mais Microsoft devrait prendre en compte cette possibilité.
Pour être clair, je ne blâme pas les développeurs, de toute façon, ils font un excellent travail, vraiment.
Juste mon 2c, désolé pour l'OT.

Je suis d'accord. Il est clair que malgré le vif intérêt de la communauté, les développeurs rejettent simplement l'idée de transformateurs/macros personnalisés sans fournir de raison du rejet, sauf quelque chose du genre "Les gens vont en abuser", ce qui semble également offensant envers la communauté. car cela implique qu'il s'agit d'une communauté de développeurs de faible qualité.

J'accepterais un rejet si une justification raisonnable autre que "Nous ne le ferons pas simplement" pouvait être fournie, mais il semble que malgré toutes les demandes de la communauté, personne n'ait encore pris la peine de fournir cela.

Je pense que c'est une critique injuste @pietrovismara. Je suis d'accord qu'il s'agit d'une fonctionnalité indispensable, mais ce n'est pas "Microsoft" qui bloque cette fonctionnalité. L'équipe, si je comprends bien, dit que ce n'est pas facile à prendre en charge et c'est pourquoi ils n'ont pas encore ajouté une telle fonctionnalité.

Encore une fois, je veux cette fonctionnalité autant que n'importe qui d'autre - mais nous devons discuter de cette question en utilisant des faits. Les faits sont que l'équipe n'est pas encore prête à le soutenir. Alors continuons à exprimer notre intérêt, mais gardons également la conversation sur la bonne voie.

@mrmckeb Si tel est le cas, je peux le comprendre. J'ai dû manquer une telle déclaration dans le grand flot de commentaires contenus dans ces numéros. Je ne voulais offenser personne, j'essayais simplement de provoquer une réponse claire des mantainers afin, comme vous l'avez dit, de maintenir la conversation sur la bonne voie.

C'est bon, c'est frustrant que le support pour cela n'existe pas - comme je l'ai dit, je le sens, et on nous demande tout le temps une sorte de solution pour les modules CSS à l'ARC maintenant que nous avons le support TypeScript. J'espère que ça viendra bientôt, mais je comprends aussi que cela ouvre une énorme zone de risque pour l'équipe.

... toujours en attente :(

oui, toujours en attente..., mais en attendant quoi, est-ce que quelque chose a été fait ?

Existe-t-il une meilleure solution que ttypescript maintenant?
Les développeurs TypeScript prévoient-ils éventuellement de prendre en charge les plugins ?

Vous pouvez créer votre propre compilateur ;-)

Des news sur le sujet ? Il me semble que la communauté a suffisamment utilisé cette fonctionnalité pour s'asseoir, recueillir des commentaires et enfin ajouter la prise en charge des transformateurs au fichier de configuration. Il existe même de nombreuses implémentations à utiliser comme référence.

Cela fait plus de 2 ans (wow!)*. Les gens sont-ils ouverts à repenser les avantages et les inconvénients de l'ouverture de plugins pour les transformateurs ?

J'ai l'impression que les préoccupations initiales qui existaient il y a tout ce temps, telles que le manque de documentation sur l'API et la nécessité de prendre en charge le maillage de l'API usercode <-> transformers <->, ne sont plus aussi pertinentes. La prise en charge des plugins ouverts a fait des merveilles pour des packages comme babel : progression par la collaboration. Je peux personnellement attester de Babel en particulier, l'ayant largement utilisé.

Une intégration plus facile "fonctionne juste" des transformateurs comme le typescript-est _serait_ agréable. Ce paquet en particulier, je le considère comme ayant une influence révolutionnaire sur le tapuscrit dans son ensemble. De vrais contrats solides ! 😃

Je pense qu'une conversation sur les avantages et les inconvénients aiderait à dissiper tout découragement ou divergence à ce sujet. J'ai l'impression que ce problème de zombies continuera jusqu'à ce que cela se produise - pour être honnête.

* Et en attendant, quelqu'un crée la fonctionnalité pour TS à la place ( ttypescript ). J'ai utilisé cela pour réussir.

@DanielRosenwasser J'ai vu qu'il y avait "Investigate TypeScript plugin APIs" sur le plan d'itération 3.5 (et que le travail a déjà commencé dessus).
Ce point traite-t-il de ce qui est discuté dans ce numéro ? L'absence de lien vers un problème me fait supposer que c'est trop de WIP pour partager quoi que ce soit à ce sujet?

Je pense qu'il faudrait travailler sur l'ajout d'une prise en charge complète de l'analyseur Babel, ce qui inclut l'ajout des fonctionnalités nécessaires pour que Babel prenne en charge l'analyse statique Typescript (par exemple, plusieurs transformations de fichiers ou la dépendance à plusieurs fichiers pendant la transformation). Plutôt que d'avoir à dupliquer la syntaxe/transformer les plugins Babel en équivalents Typescript.

au cas où vous auriez des problèmes avec les instructions suivantes, faites le moi savoir, je serai heureux de vous aider

étant donné la pure négligence de l'équipe de conception, voici une solution de contournement

nous allons profiter de tslint et de ses capacités de correction de code

dans l'exemple suivant, nous allons faire une transformation de type en code , dans sa forme la plus basique

nous allons utiliser des décorateurs comme marqueurs d'endroits dans le code qui doivent être réécrits

dans notre cas, un décorateur est une fausse fonction dont le seul but est

  • marquer un lieu de la transformation
  • et pour capturer le type qui va être la source d'information pour le générateur

à des fins de démonstration, nous allons vider les noms et les types de propriétés d'une interface sous forme de chaînes simples, dans une classe sous-jacente

les étapes suivantes sont réservées aux utilisateurs de Windows, si vous n'êtes pas l'un d'entre eux, que Dieu vous aide :

  1. démarrez votre VSCode
  2. installez l'extension suivante : https://github.com/Microsoft/vscode-typescript-tslint-plugin
  3. fermez votre VSCode
  4. allez dans un dossier de votre choix
  5. courir git clone https://github.com/zpdDG4gta8XKpMCd/code-gen.git
  6. allez dans le dossier code-gen : cd ./code-gen
  7. Cours

    • 1-install.bat

    • 2-build.bat

    • 3-install-some-more.bat

    • 4-try.bat

  8. observer une instance de VSCode ouverte
  9. aller à test.ts ( Ctrl + P -> test.ts )
  10. prenez note de l'interface suivante, ce sera la source du générateur de code
interface Data {
    one: string;
    another: number;
}
  1. notez la fonction suivante, qui comporte un décorateur fantôme que nous allons utiliser comme marqueur
function gen<_T>() {
    return function (meh: any) {};
}
  1. prenez note du site de réécriture, où nous voulons pousser du code auto-généré basé sur l'interface et le décorateur de marqueurs
@gen<Data>()
export class Gen {
}
  1. observez une ligne sinueuse sous @gen<Data>()
    image

  2. choisissez Quick fix... -> Needs a rewrite, wanna fix?
    image

  3. observez le code généré automatiquement :
    image


pour référence voici le code source du générateur que vous pouvez trouver dans codeGenRule.ts

import * as Lint from 'tslint';
import * as ts from 'typescript';

export class Rule extends Lint.Rules.TypedRule {
    public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
        return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program.getTypeChecker()));
    }
}

class Walker extends Lint.RuleWalker {
    constructor(sourceFile: ts.SourceFile, options: Lint.IOptions, private checker: ts.TypeChecker) {
        super(sourceFile, options);
    }
    public visitNode(node: ts.Node) {
        if (ts.isDecorator(node)) {
            const checked = check(node, this.checker);
            if (checked !== undefined) {
                const [node, message, replacement] = checked;
                this.addFailureAtNode(node, message, replacement);
            }
        }
        super.visitNode(node);
    }
}

function check(node: ts.Decorator, checker: ts.TypeChecker) {
    const { expression, parent } = node;
    if (!ts.isClassDeclaration(parent)) return;
    if (!ts.isCallExpression(expression)) return;
    const { expression: identifier, typeArguments: typeArgs } = expression;
    if (!ts.isIdentifier(identifier)) return;
    const { text: name } = identifier;
    if (name !== 'gen') return;
    if (typeArgs === undefined) return;
    if (typeArgs.length > 1) return;
    if (typeArgs.length < 1) return;
    const [only] = typeArgs;
    const type = checker.getTypeFromTypeNode(only);

    // if you got to here, you are at the right place and you have a type

    // working on a fix
    const properties = checker.getPropertiesOfType(type);
    const allNameTypes = properties.map(p => {
        const { name } = p
        const type = checker.getTypeOfSymbolAtLocation(p, node);
        return name + ': \'' + checker.typeToString(type) + '\';'
    })
    const { newLine } = ts.sys;
    const body = newLine + allNameTypes.join(newLine);
    const { pos: start, end } = parent.members;
    return [
        node,
        'Needs a rewrite, wanna fix?',
        Lint.Replacement.replaceFromTo(start, end, body)
    ] as const;
}

@zpdDG4gta8XKpMCd , merci d'avoir partagé votre concept - mais s'il vous plaît soyez civil.

étant donné la pure négligence de l'équipe de conception, voici une solution de contournement

Ce n'est pas la bonne façon d'aborder le TypeScript pour ne pas implémenter une _fonctionnalité_ que vous (et beaucoup d'autres, y compris moi-même) aimeriez avoir. Ce n'est pas un défaut majeur et ne reflète pas une "négligence". Veuillez être respectueux.

oh s'il vous plaît ne le prenez pas personnellement, c'est juste la façon dont je commence toujours mes plaintes, j'ai une personnalité très aigre (condition médicale) et c'est le mieux que je puisse faire de moi-même, je suis vraiment désolé

vous n'allez pas arrêter de me surprendre

  • ce que vous voyez est un morceau de code qui semble capable de résoudre un problème majeur d'aujourd'hui avec confort (pas de trucs, pas de piratage)
  • cette solution de contournement est un signal d'alarme pour l'équipe de conception, et comme nous l'avons vu auparavant lorsque la communauté était sur le point de prendre un virage dans la mauvaise direction, l'équipe de conception était là pour y remédier rapidement : #4212,
  • donc s'ils s'en soucient, ils peuvent le faire bien plus tôt jusqu'à ce qu'il soit trop tard, ou s'ils ne le font pas, nous sommes libres de creuser dans cette direction et ce ne sera pas un problème pour eux plus tard
  • donc le ton de mes commentaires était quelque chose d'inapproprié, mais tout ton ton approprié ne t'a rien donné depuis le 2 mars 2017 (sur 2 ans), et oui, tu peux attendre encore 2 ans

@zpdDG4gta8XKpMCd Qu'avez-vous contribué à une implémentation réelle ? TypeScript est open source ; Je ne doute pas qu'ils envisageraient sérieusement une pull request si vous en créiez une (même partiellement).

Blâmer votre grossièreté sur une condition médicale est inacceptable ; ce sont des mots que vous avez tapés et que vous avez volontairement choisi de cliquer sur "commentaire". Aucune condition médicale ne vous oblige à faire cela. Parlez, peut-être, pas tapez. Vous avez également eu la possibilité de modifier votre commentaire pour le supprimer, mais vous ne l'avez pas fait.

Si vous avez besoin de transformateurs personnalisés _maintenant_, vous pouvez utiliser Babel. Il peut supprimer les annotations de type de presque tous les TypeScript, tout en permettant les transformations de syntaxe aussi facilement que vous le souhaitez. En prime, c'est aussi plus rapide.

Je vous suggère d'arrêter de commenter avant d'être définitivement expulsé du référentiel de Microsoft. Je sais que si c'était mon repo, tu serais sur ta dernière paille.

ok, tu m'as viré, alors quoi
puis-je jamais revenir? puis-je créer un nouveau compte ?
pensez-vous que je me soucie trop de ce compte ?

de toute façon, oui, j'ai essayé les pull requests, malheureusement ce n'est pas faisable pour les raisons suivantes :

  1. il y a une certaine catégorie de problèmes que vous êtes invités à résoudre, qui sont plutôt triviaux et de moindre intérêt, n'importe quoi de sérieux comme celui-ci - et vous n'êtes pas

  2. puisque vous ne pouvez pas le résoudre vous-même, un problème comme celui-ci (même avec 224 pouces levés) peut attendre des années s'il n'est jamais envisagé

  3. heureusement, vous pouvez faire quelque chose aujourd'hui en utilisant tous les moyens dont vous disposez et commencer à faire une différence visible, d'où la suggestion (ne me blâmez pas de ne rien faire)

@zpdDG4gta8XKpMCd autant que vous le sachiez, j'ai été un fan des prises cyniques au fil des ans, je dois être d'accord avec les autres ici - nous devons garder la conversation civile et respectueuse. C'est toujours un bon rappel que tous ceux qui suivent ce problème veulent améliorer le projet .


@Janpot Yup, c'est vraiment un WIP, mais quand @rbuckton reviendra, il pourra peut-être donner plus de détails sur le statut.

Alors que nous étudions les points de plugin (comme j'y ai fait allusion dans le plan d'itération 3.5), je pense que l'exposition de crochets plus faciles pour les transformateurs personnalisés est un scénario majeur que nous voulons considérer. La raison pour laquelle nous ne le ferions pas nécessairement simplement, c'est que nous pourrions avoir un travail plus large qui englobe cela. En d'autres termes, il y a peut-être quelque chose de plus large que les pré- et post-transformateurs.

@DanielRosenwasser il n'y a pas tant de cynisme là-dedans, j'ai seulement dit 2 mots et ensuite j'ai dit que j'en suis profondément désolé

Quoi qu'il en soit, je pense que nous sommes tous d'accord sur le fait qu'il y a une bonne part de frustration saine sur la façon dont les choses se passent, et nous ne vous en voulons pas, nous comprenons ce qui motive ce projet

mais si nous le regardons de notre point de vue, il doit y avoir quelqu'un à blâmer, car laisser des problèmes comme celui-ci rester assis pendant des années juste en recueillant des pouces vers le haut, c'est ce qui empêche d'être plus productif

Je suis sûr qu'il y a des raisons de le remettre à plus tard et de se concentrer d'abord sur d'autres choses, donc je pense qu'il serait préférable que vous fassiez savoir à votre public pourquoi certaines fonctionnalités très recherchées ne peuvent pas être remplies, cela pourrait réduire le degré de frustration, par exemple :

  • nous ne pouvons pas implémenter cette fonctionnalité à cause de A, BC et ceux qui nécessitent D, E et F en premier

donc je suppose que je fais référence à cette conversation: https://github.com/Microsoft/TypeScript/issues/30696#issuecomment -478799258

Avoir des pouces vers le haut ne crée pas de nouvelles ressources à partir de rien, ne rend pas simples et faciles les décisions complexes et difficiles, ne change pas les priorités commerciales existantes, n'arrête pas les projets en cours, ne donne pas la priorité à d'autres travaux, ne fait pas en sorte que des propositions trop ambitieuses deviennent bien ciblées, ou modifier une suggestion avec des impacts étendus et permanents pour devenir ciblée et maintenable.

Je n'ai aucune excuse pour nous de faire (ou d'autoriser les relations publiques pour , c'est ce dont vous vous plaigniez dans # 30696) un travail simple et bien compris avant un travail extrêmement complexe et exigeant comme celui-ci. Il ne devrait pas être difficile de deviner pourquoi nous sommes prêts à laisser quelqu'un venir réparer un robinet qui fuit alors que les plans de rénovation du sous-sol et d'ajout d'un autre étage au-dessus de la maison sont toujours en cours d'élaboration.

@zpdDG4gta8XKpMCd Pourquoi auriez-vous besoin de blâmer quelqu'un ? Pourquoi ne vous reprochez-vous pas en premier lieu de ne pas avoir fait de relations publiques pour résoudre ce problème ? Ou au moins une rédaction constructive sur la façon de l'aborder du point de vue de la mise en œuvre ?

Oh mec, même après cette écriture transparente que vous venez de lier, vous avez décidé de piquer à nouveau l'ours après seulement 2 semaines ? Essayez d'imaginer être dans cette position avec plus de 1500 tâches à accomplir et vous devez en choisir quelques-unes. Dans notre équipe, nous déplaçons environ 100 tâches et luttons assez. Je ne peux pas imaginer que ce serait 15 fois plus 😮

@FredyC pour l'amour de Dieu, regarde ma solution de contournement avant de dire que je ne fais rien

oui, je ne fais pas de demandes d'extraction formelles parce que :

  1. je ne suis pas au niveau pour en faire un bon

  2. pour les simples, il y a une longue file d'approbation, et il faut un travail énorme pour maintenir à jour une pull request créée il y a 2 ans avec la base de code actuelle, je n'ai pas beaucoup de temps

  3. certains problèmes ne seront même pas pris en compte, étant donné les considérations de grande conception dont peu de gens comme anders hejlsberg sont conscients

vous ne pouvez pas enlever la part de frustration, et je ne suis pas seul ici

nous savons que ces facteurs sont en jeu :

  • grand dessein de la langue
  • budget / ressources / politique à l'intérieur de l'État membre
  • souhaits de la communauté

je serais plus heureux si la prise de décision avec le mélange de ces ingrédients était un peu plus claire

j'ai fini, c'est allé trop loin, désolé pour tous ceux dont les sentiments ont été blessés, je ne dirai pas un mot

suite de https://github.com/Microsoft/TypeScript/issues/14419#issuecomment -483920640

une autre option consiste à utiliser les déclarations de fonction elles-mêmes comme marqueurs, ce qui est ci-dessous est une implémentation d'un générateur de code pour les fonctions dont les noms commencent par toRandom...

la source d'information pour le générateur est le type de résultat de la fonction

Voilà comment cela fonctionne:

  1. remarquez la ligne ondulée sous une fonction qui commence par toRandom...
    image
  2. explorez vos options :
    image
  3. faire une solution rapide
    image
  4. observez les résultats :
    image

voici le code de codeGenRule.ts qui le fait

en prime cette implémentation ne posera un problème de peluches que si le code actuel de la fonction ne correspond pas au code censé être généré

import * as Lint from 'tslint';
import * as ts from 'typescript';

export class Rule extends Lint.Rules.TypedRule {
    public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
        return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program.getTypeChecker()));
    }
}

class Walker extends Lint.RuleWalker {
    constructor(sourceFile: ts.SourceFile, options: Lint.IOptions, private checker: ts.TypeChecker) {
        super(sourceFile, options);
    }
    public visitFunctionDeclaration(node: ts.FunctionDeclaration) {
        const checked = check(node, this.checker);
        if (checked !== undefined) {
            const [node, message, fix] = checked;
            this.addFailureAtNode(node, message, fix);
        }
        super.visitFunctionDeclaration(node);
    }
}

function check(node: ts.FunctionDeclaration, checker: ts.TypeChecker) {
    const { name: identifier, type: result, body } = node;
    if (body === undefined) return;
    if (identifier === undefined) return;
    const { text: name } = identifier;
    if (!name.startsWith('toRandom')) return;
    if (result === undefined) return;
    const type = checker.getTypeFromTypeNode(result);

    // if you got to here, you are at the right place and you have a type

    // working on a fix
    const properties = checker.getPropertiesOfType(type);
    const newerBody =
        `{
    return {${properties.map(prop => {
            const { name } = prop;
            const type = checker.getTypeOfSymbolAtLocation(prop, node);
            const typeName = capitalize(checker.typeToString(type));
            return `
        ${name}: toRandom${typeName}(),`;
        }).join('')}
    };
}`;
    const olderBody = body.getFullText();
    if (areEqual(olderBody, newerBody)) return;
    const start = body.getFullStart();
    const end = start + body.getFullWidth();
    return [
        node,
        'Needs a rewrite, wanna fix?',
        Lint.Replacement.replaceFromTo(start, end, newerBody),
    ] as const;
}

function areEqual(one: string, another: string) {
    // AB: we cannot make any assumption what line endings are,
    // this is why we compare the text of code without them
    return one.replace(/\r\n|\n/g, ' ') === another.replace(/\r\n|\n/g, ' ');
}

export function capitalize(value: string): string {
    const length = value.length;
    if (length > 1) {
        return value.substr(0, 1).toUpperCase() + value.substr(1);
    } else if (length > 0) {
        return value.substr(0, 1).toUpperCase();
    } else {
        return value;
    }
}

@ zpdDG4gta8XKpMCd Je pense que ce problème concernait davantage la possibilité de brancher plus facilement des transformateurs personnalisés tout en émettant? Ex. en spécifiant les transformations dans tsconfig.json afin qu'elles puissent être utilisées avec tsc plutôt que d'utiliser l'api . Souhaitez-vous des modifications/corrections de code personnalisées dans l'éditeur ?

Je ne les ai pas du tout utilisés, mais je pense que ce dont vous parlez pourrait déjà être possible avec un plugin de service linguistique (je pense qu'en remplaçant getCodeFixesAtPosition sur le service linguistique et en insérant vos propres actions de code... pas sûr cependant) https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin

Ou peut-être que j'ai mal compris ?

droit. c'est exactement ce que je pensais

je pensais qu'un moyen de spécifier mes transformations personnalisées via tsconfig.json serait un rêve devenu réalité

mais ensuite j'ai réalisé que j'aimais encore mieux ma solution de contournement

voici ma ligne de pensée:

  • j'avais besoin d'un générateur de code configurable enfichable
  • tapuscrit n'a rien de tel à portée de main
  • d'un autre côté je sais que tslint (bien qu'étant déprécié d'ici la fin de 2019) est une plate-forme de plugin décente pour dactylographier qui a un moyen de brancher et de configurer votre code avec une grande liberté
  • il s'avère qu'il a tout ce dont j'ai besoin:

    • enfichable et configurable

    • avec toute l'interface utilisateur nécessaire

    • me donne une API pour taper du texte

    • a quelques petits extras

étant donné tout cela, je ne me vois pas écrire quelque chose qui utilise le service de langage dactylographié, car:

  • mon ordinateur portable ne peut contenir que de nombreux services de langage dactylographié, et certains d'entre eux le sont déjà :

    • un de vscode

    • un de tslint

et je ne veux pas en ajouter un autre en plus

J'aimerais avoir une meilleure façon de brancher mes transformateurs de code, mais nous avons ce que nous avons


et voici comment nous faisons les macros : #4892

  • mon ordinateur portable ne peut contenir que de nombreux services de langage dactylographié, et certains d'entre eux le sont déjà :

    • un par de vscode
    • un par tslint

@zpdDG4gta8XKpMCd Je pense que tout devrait utiliser le même service linguistique. Vous aurez donc un service en une seule langue, puis le plugin tslint avec votre plugin le proxy.

Au fait, ce que vous essayez de faire ici devrait certainement être possible avec un plugin de service en langage clair, car c'est ce qui est fait ici .

Quoi qu'il en soit, essayons de garder la conversation ici sur le sujet et uniquement sur les transformateurs personnalisés dans le cadre de la construction avec tsc plutôt que sur les changements de code de l'éditeur/les éléments de service de langue. La plupart des gens recherchent une solution pour effectuer une transformation sur l'ensemble d'un projet et le faire dans l'éditeur n'est pas une solution viable (d'autant plus que faire une transformation à ce stade va à l'encontre de l'objectif de les utiliser). Idéalement, ce qui devrait être implémenté ici ne devrait rien avoir à voir avec l'éditeur/tsserver ou le service de langage.

merci pour la précieuse contribution, je vais y réfléchir

Je ne suis pas d'accord avec vous pour ne garder la conversation que sur les transformateurs personnalisés dans le cadre de la construction avec tsc , puisque

  • la demande originale telle qu'elle est écrite n'est pas précise sous quelle forme se transforme à livrer, elle indique seulement qu'elle ne devrait pas nécessiter d'avoir à
    > dupliquer toute la ligne de commande tsc juste pour ajouter un seul transformateur
  • sur 2 ans, cette discussion a attiré pas mal d'attention de la part de nombreuses personnes qui ne semblent pas trop se soucier de la façon dont les transformateurs sont mis en œuvre, à condition qu'il existe une solution, cela fonctionne et c'est facile à utiliser
  • de plus, l'équipe tslint a fait du bon travail en construisant l'infrastructure pour les plugins, ne pas l'utiliser est un gaspillage d'efforts, à condition qu'il s'agisse de facto de la seule plate-forme officiellement reconnue en dehors du dactylographié qui traite du dactylographié
  • aussi, nous sommes tous d'accord que même si les transformateurs trouvent un jour leur chemin vers la langue, cela n'arrivera pas de sitôt, mais les gens ici (y compris moi-même) en avaient besoin comme hier
  • enfin, puisqu'il n'y a pas beaucoup de meilleures alternatives, pourquoi ne considérerions-nous pas au moins ce que nous avons ?

ma suggestion est clairement étiquetée comme une solution de contournement (pendant que l'équipe de conception prend son temps pour réfléchir davantage à une solution appropriée), alors pourquoi pas ?

si vous insistez pour que nous le fassions ailleurs, veuillez en parler

mais pour répondre à votre souci de faire un

transformer tout un projet

tslint fait exactement cela avec son argument --fix pour cli

@zpdDG4gta8XKpMCd --fix mettra à jour le code TypeScript en place. Ce problème concerne les transformations lors de l'émission (les modifications ne se retrouvent donc que dans les fichiers JavaScript finaux). Voir le PR du numéro référencé (#13940):

Depuis que #13764 a atterri, il est facile d'écrire des transformateurs personnalisés. Cependant, si je comprends bien l'API, il est nécessaire de dupliquer toute la ligne de commande tsc juste pour ajouter un seul transformateur. Cela conduit à des incompatibilités car ces applications, selon le type de script, ne prennent pas en charge les mêmes fonctionnalités que l'outil de ligne de commande tsc.

En d'autres termes, ce problème a rapporté CustomTransformers (cliquez sur ce lien et voyez où il est utilisé dans l'API), mais pour les utiliser, tsc doit être dupliqué d'une manière ou d'une autre ou enveloppé, ce qui est ce que ttypescript le fait. Le deuxième paragraphe explique ensuite en quoi cela serait bon car cela s'intégrerait bien dans les outils de construction existants (puisque l'utilisation des transformateurs personnalisés serait gérée par tsc plutôt que par différents outils de construction le faisant de différentes manières).

Je pense qu'il serait plus productif d'ouvrir un nouveau problème avec vos préoccupations concernant les correctifs de code ou de vouloir un moyen plus simple de générer du code TypeScript dans le code TypeScript. Je ne sais pas exactement quelles sont ces préoccupations car je pense que beaucoup d'entre elles sont déjà possibles aujourd'hui, mais ce dont vous avez discuté, c'est de la façon de corriger/actionner le code, ce qui me semble être un sujet sans rapport.

Je pense que les principales questions auxquelles répondre dans ce fil sont ce dont Daniel a discuté - "peut-être qu'il y a quelque chose de plus large que les pré- et post-transformateurs" - et à quoi ressemblerait la solution pour faire de cette partie de la construction.

tu es vague

je suis une personne qui comprend et apprécie les choses simples

mon problème est que j'ai affaire à un projet de plus de 3500 fichiers, dont 15% n'ont pas besoin d'être écrits et maintenus à la main et il y a environ 5% de choses similaires à venir

en même temps, je sais qu'il existe une API qui peut le faire pour moi, mais c'est tellement à moitié cuit que je ne peux jamais justifier mon temps à m'en occuper pour le faire complètement cuire

alors quand je suis venu ici, j'ai pensé que c'était le bon endroit pour en parler, et il s'avère qu'il pourrait y avoir une solution simple et rapide

pas de chance certaines personnes qui sont venues ici sont pour discuter de choses beaucoup plus fines

d'accord, exceptionnel !

et non, je ne vais pas ouvrir un nouveau sujet juste pour montrer aux gens une fois de plus comment tslint peut résoudre l'un des problèmes majeurs, j'ai fait mon travail, j'ai terminé

Avoir des transformations configurables prêtes à l'emploi serait bien. J'essaie de résoudre un problème de chaîne de code l10n et i18n . Je peux utiliser des outils comme tslint avec une règle personnalisée pour l'extraction, mais mes options de transformation du code sont limitées, sauf si j'utilise quelque chose comme ttypescript , mais c'est problématique parce que l'application que je suis travailler sur est une application angulaire non éjectée. Cela me force simplement à ajouter couche après couche d'outils de construction. Avec le rythme du développement, l'ensemble de la pile devient vraiment précaire.

Nous développons actuellement un framework et nous utilisons actuellement ttypescript afin d'accéder aux informations de niveau type au moment de l'exécution, ce serait bien d'avoir l'option plugins dans le compilateur officiel éventuellement 😄

Je suis en vacances en ce moment mais je regarderai la semaine prochaine quand je serai de retour

Le dim. 21 juillet 2019 à 17 h 54 Giorgio Boa [email protected]
a écrit:

@longlho https://github.com/longlho Vous avez créé beaucoup de super ast
transformateurs, j'ai besoin de votre aide s'il vous plait 👍
J'aimerais vraiment modifier les métadonnées du décorateur avant la copie angulaire.
Mon objectif est de modifier ce nœud
Component({ selector: 'standard' ... }) into Component({ selector: 'custom'
... })
J'ai fait un repo github pour le tester
https://github.com/gioboa/ng-ts-transformer . je pense que c'est possible mais
sans documentation j'ai besoin d'aide. 🙏 Merci.


Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/microsoft/TypeScript/issues/14419?email_source=notifications&email_token=AABQM335QEEDNVT4NUICJQDQASBDXA5CNFSM4DCFER5KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2OGIWQ#issuecomment 65-55
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AABQM33S5IYXB5HOZTRVVX3QASBDXANCNFSM4DCFER5A
.

J'ai contribué à créer une bibliothèque pour créer de vrais mocks à partir d'interfaces sans proxy. Je recommande d'utiliser ttypescript pour l'instant mais ce serait bien d'avoir un moyen d'intégration avec dactylographie

J'aimerais vraiment voir cette fonctionnalité arriver. Je suis presque sûr que c'est la seule chose qui se dresse entre Typescript et certaines des plus grandes innovations auxquelles il peut conduire.

Typescript est une énorme contribution au développement du frontend, mais il a également un frein à l'innovation future…
Ne cassez pas la sémantique. Aucun plugin ATM ne peut casser la sémantique ; et aucun plugin n'est autorisé du tout :man_shrugging: Pourquoi ?
Il y a vraiment de bons plugins, mais. Chaque plugin doit respecter la tokenisation des mots (clés) et l'installation AST)… , moyen très difficile de faire quelque chose à l'intérieur.
Ce n'est pas si dur. Ce n'est pas facile, mais le projet babel montre que c'est possible.
En fait, il est presque trivial pour babel d'introduire de nouvelles phrases sémantiques ou même syntaxiques.

Je ne m'attends pas à ce que le tapuscrit autorise la sémantique. (je ne m'attends pas non plus à des changements de syntaxe bien sûr!)
Ce que je souhaite, c'est que le compilateur soit décalé dans certains cas, comme (peut-être uniquement le type) preeval.
Comme si j'avais une fonction take, comme route ou message ou quelque chose comme ça, le compilateur peut preeval et (oh, s'il vous plaît, à la première phase) vérifier l'exactitude.

Si vous lisez mon paragraphe précédent bizarre. Qu'est-ce que tsx et toute la bonté de React ?

Pas de réaction, pas de flux, pas de texte dactylographié du tout, presque pas en un coup d'œil.

S'il te plaît. Je comprends bien tout cela avec un regard attentif; mais comme nous l'apprenons d'IE5.5+; le blocage n'est pas une solution.

Si quelque chose doit être amélioré, c'est toujours le moteur de mise en page. D.Knuth était guenie qui a conçu toutes les pièces manquantes il y a 50 ans. Pourquoi nous n'avons pas cela aujourd'hui ?? :-)
S'il vous plaît, dites aux gens d'arrêter le CSS dans le mal JS.

S'il te plaît. Open TS pour l'intelligence sémantique ; comme une fonction avec une entrée de chaîne statique, fournissant un indice de type pour le reste ; analyser la chaîne d'entrée const réelle…
Un petit exemple :

  • Forme de retour d'appel GraphQL
  • Forme d'entrée internationale
  • …beaucoup plus_
    S'il te plaît. Aucune modification sémantique nécessaire. Tout fonctionnera comme vous le souhaitez. Quelque chose de plus peut être vérifié au moment de la construction. C'est tout ! :lapin:

cogner

J'expérimente l'écriture de transformations TS pour l'optimisation core-js import - polyfilling automatique pour les environnements cibles, comme @babel/preset-env et @babel/runtime , mais sans babel . Cela pourrait sérieusement aider une grande partie des développeurs TS. Mais sans prise en charge des transformations personnalisées de la boîte sans outils supplémentaires comme ttypescript , la possibilité d'utiliser ces transformations sera sérieusement limitée, donc je ne suis pas sûr que cela ait un sens.

J'ai expérimenté une telle idée - https://github.com/webschik/typescript-polyfills-generator.
Je pense que l'API Transformers ouvrira la possibilité de supprimer babel de la chaîne de développement. Je pense que beaucoup de développeurs ne veulent pas les utiliser tous les deux, mais ils ont toujours besoin de plugins tels @babel/preset-env .

Nous avons actuellement déployé notre propre script de compilateur personnalisé (à l'aide de l'API du compilateur TypeScript) en raison de cette limitation. Nous avons brièvement examiné ttypescript , mais l'envie de passer du compilateur TypeScript vanille à une extension du compilateur TypeScript n'est tout simplement pas là.

Ce serait fantastique si les transformateurs personnalisés étaient pris en charge dans tsconfig.json. Il est fastidieux d'écrire un script qui analyse simplement tsconfig, déclare les transformateurs, puis exécute le compilateur ; ou, pire, d'essayer de réimplémenter les fonctionnalités fondamentales du compilateur, comme la surveillance des fichiers, dans un script personnalisé.

D'autres personnes ont fait écho à ce sentiment, mais permettre la facilité d'intégration de transformateurs personnalisés dans le compilateur allégerait considérablement la charge de l'équipe de développement de TypeScript et permettrait l'innovation et un élan supplémentaire avec ce langage de la communauté.

Un exemple d'écosystème de plugins très réussi est la communauté de plugins de Serverless Framework. L'équipe de développement ne peut pas répondre à la demande de développement de fonctionnalités, et les plugins offrent un excellent moyen de permettre l'intégration de nouvelles fonctionnalités (éventuellement expérimentales) sans avoir besoin d'ouvrir des relations publiques ou d'édulcorer le produit principal avec des fonctionnalités qui peuvent ou peuvent n'offrent pas de valeur à la base d'utilisateurs plus large.

Je construis une bibliothèque et j'ai des décorateurs qui travaillent très bien pour moi et dont je dépends. J'ai réalisé il y a quelque temps que les décorateurs rendaient ma bibliothèque inébranlable. Après avoir examiné la question, j'en suis venu à la conclusion que les transformateurs pourraient m'aider à transformer ces décorateurs en code arborescent lors de la compilation. Il est regrettable que je ne puisse pas les définir dans mon pipeline. J'espère que vous arriverez bientôt à ce problème, je voulais juste laisser tomber mes 2 cents sur un cas d'utilisation où cela serait très utile.

Dans l'intérêt de faire en sorte que TypeScript prenne en charge les transformateurs personnalisés sans programmes wrapper et instructions compliquées, j'ai écrit un outil appelé ts-patch ( npm github )

Installez simplement ts-patch (globalement ou localement) et exécutez ts-patch install pour corriger le typescript. Vous pouvez également spécifier le répertoire d'installation de typescript et/ou activer la persistance, qui maintient le correctif si TS est mis à jour ou réinstallé. (détails : ts-patch /? )

La logique du patch est principalement basée sur ttypescript. (Un grand merci à l'excellent travail de cevek !) Il est écrit de manière à pouvoir être facilement ajouté au processus d'installation du package npm. Il est également facile à dépatcher.

Pour être clair, cela corrige directement les fichiers pertinents dans le tapuscrit lui-même et n'est pas un wrapper. Exécutez simplement le correctif après l'installation de la dépendance et le script dactylographié sera prêt pour le transformateur.

J'espère que cela aidera certaines personnes !

Dans l'intérêt de faire en sorte que TypeScript prenne en charge les transformateurs personnalisés sans programmes wrapper et instructions compliquées, j'ai écrit un outil appelé ts-patch ( npm github )

Installez simplement ts-patch (globalement ou localement) et exécutez ts-patch install pour corriger le typescript. Vous pouvez également spécifier le répertoire d'installation de typescript et/ou activer la persistance, qui maintient le correctif si TS est mis à jour ou réinstallé. (détails : ts-patch /? )

La logique du patch est principalement basée sur ttypescript. (Un grand merci à l'excellent travail de cevek !) Il est écrit de manière à pouvoir être facilement ajouté au processus d'installation du package npm. Il est également facile à dépatcher.

Pour être clair, cela corrige directement les fichiers pertinents dans le tapuscrit lui-même et n'est pas un wrapper. Exécutez simplement le correctif après l'installation de la dépendance et le script dactylographié sera prêt pour le transformateur.

J'espère que cela aidera certaines personnes !

cela pourrait-il être soulevé comme un PR pour ajouter/discuter d'un support approprié ? :)

Hé. Pour ce que ça vaut, il existe un bundler appelé fuse-box qui permet d'ajouter très facilement des transformateurs personnalisés. Sa version 4.0 arrive bientôt... donc c'est dans une position intermédiaire. Mais dans l'ensemble, j'aime vraiment le bundler. Peut-être que cela peut vous aider aussi.

https://github.com/fuse-box/fuse-box/blob/master/docs/plugins/pluginCustomTransform.md

cela pourrait-il être soulevé comme un PR pour ajouter/discuter d'un support approprié ? :)

L'équipe TS a indiqué qu'elle ne souhaitait pas fournir cette fonctionnalité en tant que fonctionnalité native. Leurs raisons de la décision ont du sens!

La bonne nouvelle est que, comme TS est open source et qu'il est déjà compilé de manière modulaire, ts-patch se comporte de la même manière qu'il le ferait s'il était intégré. Il ne s'agit donc pas d'un patch buggy de bytecode rétro-conçu.

Si par support, vous êtes préoccupé par sa maintenance, je prévois de le maintenir à jour et de le faire fonctionner pour toutes les futures versions de TS ! Une grande partie de mon infrastructure commerciale en dépend déjà.

En passant, je publierai bientôt une nouvelle version qui permet de regrouper plusieurs plugins avec différents points d'entrée dans un seul package ainsi que d'autres optimisations pour l'améliorer et le rendre plus facile à utiliser.

Après avoir écrit un plugin, je peux comprendre pourquoi l'équipe ts hésite - le transformateur de courant est une étape post-compilation. Vous rencontrez des problèmes désagréables si vous faites quelque chose de compliqué et que vous commencez à ajouter un nouveau contenu qui n'était pas lié à l'origine. Dans l'état actuel des choses, ts-node --compiler ttypescript foo.ts fonctionne parfaitement bien. Je préfère que l'équipe ts s'occupe des plugins de transformateur à différentes étapes de compilation... ou autorise une étape de reliure.

Le transformateur de courant est une étape de post-compilation. Vous rencontrez des problèmes désagréables si vous faites quelque chose de compliqué et que vous commencez à ajouter un nouveau contenu qui n'était pas lié à l'origine.

Les transformateurs peuvent s'exécuter avant ou après la compilation TSC. Il semble que ce à quoi vous faites référence est que le vérificateur ne se met pas à jour après la modification des nœuds. Cela peut en fait être contourné, la fonctionnalité n'a tout simplement pas été conçue pour cela. Lorsque vous appelez ts.transform(), il ne crée pas d'instance de programme complète avec laquelle vous pouvez travailler, donc si vous voulez travailler avec le vérificateur, vous devez en créer un. En utilisant CompilerHost, vous pouvez le recharger avec les fichiers modifiés après avoir modifié l'AST.

Je ne suis pas encore allé trop loin, mais il semble qu'il soit également possible d'utiliser la fonctionnalité 'watch' pour éviter d'avoir à reconstruire l'intégralité de l'instance du programme à chaque fois. En termes simples, il s'avère qu'il n'est pas vraiment _trop_ difficile d'avoir un système de plugins plus complet, mais transform manque simplement de support dans son contexte fourni.

@nonara J'ai utilisé des transformations avec ttypescript et ts-loader`, les deux ont des points d'entrée de programme complets. Mon problème est que si vous ajoutez une nouvelle instruction d'importation, il manque "quelque chose" et ces nouvelles instructions sont supprimées de la sortie finale. @weswigham dit que c'est parce que la transformation est une étape post-liaison . La solution est apparemment de créer un programme entièrement nouveau pour le fichier - mais cela semble être un casse-tête lorsque vous avez affaire à des choses comme ts-loader (en particulier lorsqu'il est en mode de transformation uniquement et masque complètement le fichier webpack/bundler- À la fin , j'ai laissé tomber l'importation et j'ai juste inséré le code dont j'avais besoin .

@MeirionHughes Ah, d'accord. Dans ce cas, oui, vous avez une instance de programme. ttypescript fonctionne en accrochant createProgram pour corriger la méthode d'émission résultante program afin d'inclure les transformateurs.

  • ts.emitFiles appelle ts.transformNodes pendant le processus.
  • ts.transformNodes peut être appelé avec ou sans instance de programme. Appeler directement ts.transform() le fait sans un.

Si je comprends bien, il semble que votre problème soit également lié au fait que les types et symboles ont déjà été parcourus et qu'ils ne sont pas mis à jour après la transformation AST.

Salut tout le monde, j'ai rédigé un manuel du transformateur pour regrouper toutes les informations sur les transformateurs ainsi que pour faciliter le démarrage.

https://github.com/madou/ts-transformer-handbook/blob/master/translations/en/transformer-handbook.md

J'adorerais quelques yeux dessus si vous pouvez épargner une seconde 👍

@madou J'ai aussi écrit un tas d'articles sur les transformateurs TS https://levelup.gitconnected.com/writing-typescript-custom-ast-transformer-part-1-7585d6916819

Où en est-on ?

J'aime beaucoup le tapuscrit, mais cela semble particulièrement maladroit lorsque vous commencez à interopérer entre les types statiques et le JS d'exécution. Il existe de nombreux plugins écrits par la communauté pour améliorer cela, par exemple https://github.com/dsherret/ts-nameof , https://github.com/kimamula/ts-transformer-keys - mais sans prise en charge de plugin de première classe cela ressemble à une décision technique risquée de les inclure dans un projet. L'activation native des plugins permettrait à la communauté de jouer avec les futures fonctionnalités potentielles de dactylographie, avant qu'elles ne soient incluses dans la bibliothèque principale.

Je pense que l'équipe TypeScript devrait reconsidérer son argumentation. L'écosystème de plugins est un moyen éprouvé de faire avancer le langage, permettant (et encourageant) des expériences (voir Haskell avec ses pragmas).

Certaines de ces expériences seront sauvages et folles, et certaines finiront par se stabiliser et deviendront courantes. Il est toujours bon de fournir la possibilité d'implémenter des fonctionnalités linguistiques dans l'espace utilisateur.

En général, la position de l'équipe TypeScript semble inutilement rigide.

Il existe également des transformations qui ne changent pas la langue mais fournissent des informations supplémentaires pour faciliter le débogage.

Par exemple , babel-plugin-transform-react-jsx-source fait partie du préréglage de transpilation de réaction par défaut ( @babel/preset-react ).
Il transforme

<sometag />

Dans

<sometag __source={ { fileName: 'this/file.js', lineNumber: 10 } } />

Ces informations permettent react de fournir de meilleures traces de pile d'erreurs pendant le développement.

Pour le tapuscrit, il n'y a pas de moyen standard d'obtenir la même chose, bien qu'il existe une transformation open source : https://github.com/dropbox/ts-transform-react-jsx-source

Je comprends que @mhegazy a mentionné deux fois que l'équipe TS n'a pas l'intention d'inclure des "plugins" dans le cadre de tsconfig. Quel est le raisonnement derrière cela ?

Seriez-vous ouvert à un PR ? La façon dont ttypescript gère les transformateurs via tsconfig est plutôt agréable.

Cas d'utilisation :

1) générer des types d'interface pour les schémas afin qu'ils puissent être vérifiés à l'exécution.
2) importer json avec des chaînes en tant que littéraux afin que le script typographique ne vomisse pas lorsqu'il est attribué à un type avec des unions discriminées.
3) importer css/yaml et d'autres objets comme la syntaxe
4) faire des requêtes graphql qui créent dynamiquement les bons types
5) compiler jsx en chaînes html afin qu'elles puissent être injectées en innerHTML
5) réécriture des importations absolues en importations relatives basées sur les chemins tsconfig.

La liste se rallonge de plus en plus. L'api du plugin est sympa. Merci de l'avoir atterri. Avoir des "plugins" dans "tsconfig" rend tsc vraiment puissant. Y a-t-il quelque chose de grand qui nous manque ?

vous pouvez également effectuer de nombreuses optimisations de performances. J'ai écrit https://github.com/atlassian-labs/compiled-css-in-js avec des transformateurs dactylographiés 🤙 serait cool si les consommateurs n'avaient pas besoin de sauter à travers des cerceaux pour l'utiliser.

Chère équipe Typescript, s'il vous plaît, arrêtez de vous traîner les pieds sur ce <_<

Où en est-on ?

Statut?

Amis quelles nouvelles?

L'équipe de dactylographie a décidé contre cette idée - si vous avez besoin de flexibilité ou d'un meilleur outil de développement, l'utilisation de dactylographie n'est pas une option sans hacks - optez plutôt pour babel et utilisez dactylographie uniquement pour la vérification de la frappe

L'équipe de dactylographie a décidé contre cette idée - si vous avez besoin de flexibilité ou d'un meilleur outil de développement, l'utilisation de dactylographie n'est pas une option sans hacks - optez plutôt pour babel et utilisez dactylographie uniquement pour la vérification de la frappe

Mais que se passe-t-il si je veux des hacks pour la vérification de type ? J'écris un petit transformateur qui fait un peu de magie :

type Human = {
    name: string,
    age: number
}

const isValid = check<Human>({ name: 'Carl', age: 16 }) // => true
const isValid = check<Human>({ name: 'Carl' }) // => false

Fonction check transformée en fonction de type-guard spécifique ! Comment puis-je le faire avec Babel? Actuellement, je devrais utiliser ttypescript...

L'équipe de dactylographie a décidé contre cette idée - si vous avez besoin de flexibilité ou d'un meilleur outil de développement, l'utilisation de dactylographie n'est pas une option sans hacks - optez plutôt pour babel et utilisez dactylographie uniquement pour la vérification de la frappe

Il est en fait question que cela devienne soutenu à l'avenir. Cela dit, il est vraiment déjà pris en charge. L'API du compilateur TypeScript prend en charge les transformateurs, et il est _vraiment_ simple d'écrire un compilateur personnalisé qui utilise des transformateurs en seulement quelques lignes de code.

Mais pour vous faciliter la tâche, vous pouvez utiliser ttypescript ou ts-patch .

Ces bibliothèques ne sont pas vraiment des "hacks" dans le sens où elles n'augmentent pas le compilateur pour ajouter la capacité de transformer. Au lieu de cela, ils exposent simplement la fonctionnalité existante de l'API du compilateur à tsc , ce qui la rend utilisable via tsconfig.

@ilya-buligin si je comprends bien votre cas d'utilisation, vous pouvez déclarer une constante ambiante

declare const check: <T>(value: unknown) => value is T;

const isValid = check<Human>({ name: 'Carl', age: 16 }) // => true

Typescript compilera le code en s'appuyant sur la définition de type check , puis vous le remplacerez par un code généré à l'aide de Babel.

@just-boris comment puis-je accéder au type générique <T> à Babel ?

Ce fil devient assez répétitif et hors sujet. @RyanCavanaugh Peut-être que ce fil devrait être verrouillé, jusqu'à ce que vous ayez des mises à jour sur le sujet.

Cette page vous a été utile?
0 / 5 - 0 notes