What is the process for including or excluding a modifier from a sentence?

I've been experimenting with the TypeScript compiler API for transforming TypeScript code, but I'm struggling to find a concise method for adding or removing modifiers in a generic way. The solution I currently have is as follows:

function removeDeclareModifier(s) {
    let modifiers;
    // Remove declare modifiers
    if (s.modifiers) {
        modifiers = s.modifiers.filter(m => m.kind !== ts.SyntaxKind.DeclareKeyword);
    } else {
        return s;
    }

    switch (true) {
        case ts.isVariableStatement(s):
            return ts.updateVariableStatement(s, modifiers, s.declarationList);
        case ts.isTypeAliasDeclaration(s):
            return ts.updateTypeAliasDeclaration(s, s.decorators, modifiers, s.name, s.typeParameters, s.type);
        case ts.isInterfaceDeclaration(s):
            return ts.updateInterfaceDeclaration(s, s.decorators, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members);
        case ts.isEnumDeclaration(s):
            return ts.updateEnumDeclaration(s, s.decorators, modifiers, s.name, s.members);
        case ts.isClassDeclaration(s):
            return ts.updateClassDeclaration(s, s.decorators, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members);
        case ts.isFunctionDeclaration(s):
            return ts.updateFunctionDeclaration(s, s.decorators, modifiers, s.asteriskToken, s.name, s.typeParameters, s.parameters, s.type, s.body);
        default:
            return s;
    }
}

However, this approach feels overly verbose and prone to errors if the function signatures change. I came across a suggestion to replace the modifiers array, but unfortunately s.modifiers is read-only in TypeScript, making that route impossible.

Is there a more efficient way to update modifiers without reconstructing the entire AST node?

Answer №1

To implement a transformation in TypeScript, you can use the ts.transform function.

Check out this guide for writing your first transformer on GitHub

  const result = ts.transform<ts.SourceFile>(sourceFiles, [transformer]);

  function transformer<T extends ts.Node>(context: ts.TransformationContext) {
    return (rootNode: T) => {
        function visit(sourceFile: ts.Node): ts.Node {

            return ts.visitEachChild(sourceFile, (node) => converNode(node), context);
        }

        function convertNode(node: ts.Node) {

            return ts.visitEachChild(node, visitChildren, context);

            function visitChildren(child: ts.Node): ts.Node | undefined {
                if (child.kind == ts.SyntaxKind.ExportKeyword) return undefined;
                if (child.kind == ts.SyntaxKind.AsyncKeyword) return undefined;

                return ts.visitEachChild(child, visitChildren, context);
            }

         
        }

        return ts.visitNode(rootNode, visit);
    };
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a Problem with Angular 2 RC HTTP_PROVIDERS

I recently upgraded my Angular 2 application to the RC version. Everything was working smoothly until I included HTTP_PROVIDER and created a service.ts file. However, now I am encountering an error: (index):14 Error: SyntaxError: Unexpected token <( ...

Retrieve a single record in Angular/Typescript and extract its ID value

There is data stored in a variable that is displayed in the Chrome console like this: 0: @attributes: actPer: "1", id: "19" 1: @attributes: actPer: "1" id: "17" etc To filter this data, the following code was used: myvar = this.obj.listR ...

transform json array into a consolidated array by merging identical IDs

I need to transform an array into a different format based on the values of the ID and class properties. Here is the initial array: const json = [{ "ID": 10, "Sum": 860, "class": "K", }, { "ID": 10, "Sum": 760, "class": "one", }, { "ID": ...

Increase the ngClass attribute's value

Is there a way to automatically increment a numeric value in a class using the ngClass directive? For example, can we achieve something like this: <some-element [ngClass]="'class-*'">...</some-element>, where the asterisk (*) will in ...

Error encountered during the deployment of Ionic 3 with TypeScript

After completing the development of my app, I ran it on ionic serve without any issues. However, when compiling the app, I encountered the following error message. Any assistance in resolving this matter would be greatly appreciated. [15:40:08] typescri ...

Maintain hook varieties during implementation of array deconstruction

I have been developing a straightforward hook to export animation helper and element reference. import { gsap } from 'gsap'; import { useRef } from 'react'; export function useTween<R extends gsap.TweenTarget>(vars: gsap.TweenVar ...

Encountering an error while testing Jasmine + Angular with Typescript: "TypeError: 'undefined' is not an object."

I'm having some difficulty while trying to test a specific service. It seems that I am struggling to match the mock response correctly: public getCustomerDetails(customerID:string): ng.IPromise<ICustomerDetails> { return this.testService.g ...

Customizing tsconfig.json: Enhancing an existing object by adding new keys in TypeScript

Is it possible to achieve the following functionality by default? let j = {a:1}; j.b = 2; I am aware that there are alternative solutions, but I am curious if this specific task can be accomplished by solely modifying tsconfig.json? ...

Tips for utilizing JSON in a TypeScript file within a Node.js environment

I have been working on implementing JSON type in my Node.js application, but I am encountering some data in a scripted format. Here is the response: }, data: '\x1F\b\x00\x00\x00\x00\x00\x00\x00]PMo0\f ...

What is the best way to transition a connected component from a class-based to a functional component in TypeScript?

I'm in the process of switching from a class-based component to a functional component. This is a connected component that uses mapState. Here is my initial setup: import { connect } from 'react-redux' import { fetchArticles } from '. ...

The value of Component variable is not defined

I am facing an issue with my User variable being undefined after calling my service. Here is the code snippet : import { User } from './user/user'; import { AppService } from './app.service'; import { Component, OnInit } from '@an ...

Style your progress bar using styled components

I am experiencing issues with my code where only the style appearance: none; seems to be working. I have been following a tutorial on building a progress bar component using ReactJS styled components, which can be found at this link: . Can anyone pinpoin ...

Simulating dependencies of Angular 2 components during unit testing

Struggling with accessing mocked service methods in Angular 2 during component unit testing. Seeking guidance on a standard approach, despite following Angular docs closely. The challenge lies in reaching the mocked service's methods. My immediate go ...

Troubleshooting: Why the OnPush change detection strategy may not be

Parent.component.html <app-child [activeUser]="activeUser" *ngIf="eceConfirm && activeUser"></app-child> Parent.component.ts During the initialization of the component, the getAllEmployees method is called to fetch ...

"Dividing" a task stream/executer

Consider the following action type: interface SaveFoo { type: 'SAVE_FOO' payload: { id: string value: number } } I have a requirement to implement a saga that will apply throttling selectively. For instance, if the following actio ...

Retrieve a designated text value from a Promise

I have developed a React/Next.js application that utilizes what3words to assign items to specific locations. The code I've created processes the what3words address, converts it into coordinates, and is intended to display the location on a Mapbox map. ...

Transform a row in an ng Smart table to a routerlink using Angular 2

I've been exploring ng2 Smart Table and I'm looking to convert a row (or even cell data) into a clickable link using routerlink. The current method I'm employing to retrieve some of my row's data is as follows: onUserRowSelect(event) ...

Two tags attached to four hypertext links

Within my HTML code, I have hyperlinks present on every line. However, I am seeking to eliminate these hyperlinks specifically from "your previous balance" and "your new balance".https://i.sstatic.net/ekVGT.png In the following HTML snippet: <tr *ngFor ...

What sets apart the Partial and Optional operators in Typescript?

interface I1 { x: number; y: string; } interface I2 { x?: number; y?: string; } const tmp1: Partial<I1> = {}, tmp2: I2 = {}; Can you spot a clear distinction between these two entities, as demonstrated in the above code snippet? ...

Specializing in narrowing types with two generic parameters

In my current project, I am working on a function that takes two generic parameters: "index" which is a string and "language" which can also be any string. The goal of the function is to validate if the given language is supported and then return a formatt ...