Tips for verifying the variable type in a TypeScript ESLint custom rule

Trying my hand at creating a custom TypeScript-eslint rule that requires the callee's object of a node to be of a specific type, which I'll refer to as MyType. Utilizing the CallExpression from typescript-eslint in the code snippet below:

Source code:

interface MyType {
   ...
}

const someVariable: MyType = ...;

Custom TypeScript-eslint rule:

export const rule = createRule({
  name: 'specific-rule',
  meta: {
    type: 'problem',
    docs: {
      description: 'detailed description',
      recommended: 'error',
    },
    schema: [],
    messages,
  },
  defaultOptions: [],
  create: (context) => {
    return {
      CallExpression(node: TSESTree.CallExpression) {
        const services = ESLintUtils.getParserServices(context);
        const checker = services.program.getTypeChecker();

        const callee = node.callee;
        const object = callee.type === 'MemberExpression' ? callee.object : null;

        if (object === null) {
          return;
        }

        const type = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(object));

        const isMyType = (
          object.type === 'Identifier' &&
          (type as any)?.symbol?.escapedName === 'MyType'
        );

        if (isMyType) {
          [... perform necessary actions here]
        }
      },
    };
  },
});

Encountering an issue where the symbol or escapedName is undefined, preventing it from being equal to 'MyType'. Is there a more effective method to verify if a callee's object matches a specific type?

Answer №1

Based on feedback, the issue can be resolved using TS template literals alone without relying on an ESLint rule. Invalid invocations will result in compile-time errors. TS template literals enable TS to comprehend the structure of a string that can be statically analyzed.

There is a limitation here where the first argument must be provided directly, as it cannot be constructed through a variable made up of other strings. However, this restriction would also apply when using ESLint.

type StringToTuple<S extends any, A extends any[] = []> =
  S extends `${string}{}${infer Rest}`
    ? StringToTuple<Rest, [...A, any]>
    : A;

const format = <S extends string>(inputStr: S, ...args: StringToTuple<S>): string  => {
  return inputStr // Implement custom logic here
}

const result1 = format('something {} something {}', 10, 'two');  // OK
const result2 = format('something {} something {}', 'one', 'two', 'three');  // Compile error
const result3 = format('something {} something {} something {}', 'one', 'two', 'three');  // OK

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

Angular8: Adjusting Activity Status After Leaving Page

When performing activities like upload, download, delete, and edit, I display statuses such as 'upload started' or 'upload completed'. This works perfectly when staying on the same page. However, there are instances where a user may nav ...

Using Firebase orderByChild to access a nested object in the database

In my current project, I am utilizing a real-time database with the following data structure: { "users": { "1234": { "name": "Joe", "externalId": "384738473847", }, ...

Guide on accomplishing masking in Angular 5

I'm curious if it's achievable to design a mask in Angular 5 that appears as follows: XXX-XX-1234 Moreover, when the user interacts with the text box by clicking on it, the format should transform into: 1234121234 Appreciate your help! ...

Extending parent context in dependencies through OOP/Typescript as an alternative to using "extends"

Introducing a custom class called EventBus has been a game-changer for me. This class allows for easy attachment of on/off/once methods to any class that extends it, enabling the creation of an array of events that can be listened to. Currently, I find my ...

Issue with loading CSS in Angular 8 upon refreshing the page after building in production

Here is the structure of my index.html: <!doctype html> <html lang="hu"> <head> <meta charset="utf-8"> <title>WebsiteName</title> <base href="/"> <meta name="viewport& ...

Guide on navigating to a different page using a function with router link in Angular using TypeScript

Trying my hand at Angualar and Typescript for the first time. I am working on creating a login page where users can move to another page if their credentials are correct. To achieve this, I want to use a function that is triggered by clicking a button. How ...

How to transfer the label text value from html to .ts file in Ionic 3?

Hey everyone! I just started using Ionic and I'm wondering how to pass the value of a label text from HTML to the .ts file. Here's a snippet of my code: <div class="box" (click)="openChatBot()"></div> <ion-label>LEADER ...

Sharing enums between client and server code in Webpack is a smart way to improve

I'm currently working on a project setup that looks like this: | |--public-|file1.ts | |enum.ts | |--server/file2.ts | The issue I am facing is incorporating the enum defined in enum.ts into both file1 and file2. While file1 can import and u ...

Saving JSON format in VueX State Management

I'm relatively new to using Vue/VueX and I am exploring methods for storing JSON data in the VueX state. Initially, it seemed like a simple task: state { jsonthing: { ... } } However, I encountered an issue where getters return an Observer type ins ...

What advantages does CfnAppSync provide over using AppSync in a CDK project?

We are in the process of enhancing our API by adding new JS resolvers and phasing out the VTL resolvers for an AWS AppSync CDK project, specifically built with Cfn<> Cloud Front CDK. The code snippet below illustrates how this can be achieved: ...

Enable lazy loading to retrieve the current routed module

I'm currently working on a way to exclude a component when a specific module is routed in a lazy loading application. For instance, in my AppComponent I have a router-outlet and a component above it: <div> <my-component></my-compo ...

Inactive function

I have a function that inserts my articles and I call this function on my page. There are no errors, but the next function retrieveAllArticles() is not being executed. public saveAllArticles(article) { for(let data in article) { this.db.exec ...

What steps do I need to take in order to set up InfluxDB with Nest

As a beginner in the world of software development, I am eager to expand my knowledge and skills. Has anyone had experience operating influxdb with nestjs? If so, I would greatly appreciate it if you could share your past experiences. Thank you for takin ...

Error: TypeScript compilation failed due to absence of tsc command in the system

Hello, I recently installed TypeScript and encountered an issue when trying to initialize tsc -v in the terminal. The error message I received was "bash: tsc: command not found." During the installation process, I used npm install -g typescript@latest whi ...

Can Typescript restrict a value to only exist within a specified set of key names within the same object?

I am completely new to Typescript and I am fascinated by the way it can check types. One thing I would like to know is if Typescript can be used to verify at compile time whether a value's domain falls within a predefined set of key names that are de ...

Using Angular to parse intricate JSON data

Need help parsing an http request in the following format: [ { "id": 1, "date": "2022-01-13T00:00:00.000+00:00", "time": "2022-01-13T21:21:21.000+00:00", "office&quo ...

Check out the selected values in Ionic 3

I am trying to retrieve all the checked values from a checkbox list in an Ionic3 app when clicked. Below is the code snippet: <ion-content padding> <ion-list> <ion-item *ngFor="let item of items; let i= index"> <ion-label>{{i ...

Eslint was unexpectedly unable to detect any errors in the .ts files

After creating a SvelteKit project with npm create svelte@latest, I included some .ts files for a particular library. However, when running eslint ., it fails to detect any errors. The default eslint config generated from Svelte is as follows: .eslintrc. ...

Refresh Form Following Submission

When using a react form that triggers a graphql mutation upon button click, the text entered in the form fields remains even after the mutation has been executed. This necessitates manual deletion of text for subsequent mutations to be run. Is there a way ...

Having issues with Craco not recognizing alias configuration for TypeScript in Azure Pipeline webpack

I am encountering an issue with my ReactJs app that uses Craco, Webpack, and Typescript. While the application can run and build successfully locally, I am facing problems when trying to build it on Azure DevOps, specifically in creating aliases. azure ...