Prevent dividing TypeScript branded types by using the `eslint no-restricted-syntax` selector

I have defined a custom TypeScript type as follows:

export type Milliseconds = number & { __type: 'milliseconds' };

and I want to restrict the usage of the division operator on this type, like so:

const foo = 1 as Milliseconds;
const bar = foo / 2;

To achieve this, I have created an ESLint rule:

"no-restricted-syntax": [
    "error",
    {
        "selector": "BinaryExpression[left.typeAnnotation.typeName.name='Milliseconds'][operator='/']",
        "message": "Milliseconds cannot be divided directly, please use the msDivide()."
    },
],

However, the rule only works when casting to milliseconds right before dividing, resulting in an error for this scenario:

const foo = 1;
const bar = foo as Milliseconds / 2;

But it does not work for this case:

const foo = 1 as Milliseconds;
const bar = foo / 2;

After experimenting with the AST using: , it appears that the issue lies in the representation of the typeAnnotation in the identifier for foo.

Is there a way to write a selector that can infer the type of left based on its name?

Answer №1

AST manipulation is the key focus of selectors. The no-restricted-syntax rule limits you to a single selector that targets one node for analysis - keeping it simple by design.

To perform this specific check, creating a custom rule is necessary. While approachable in cases like yours with scope evaluation, a more comprehensive solution demands type-awareness due to limitations across function or module boundaries.

Illustratively, consider the following code:

// fileA.ts
declare function getCurrentTimeMillis(): Milliseconds;

// fileB.ts
import { getCurrentTimeMillis } from './fileA';

const x = getCurrentTimeMillis();
const y = x / 2; // ❌ OOPS

Type inference becomes essential for such evaluations - enabling identification of variables like x as Milliseconds.

Hence, a generic approach for your custom rule might involve:

  1. Identifying binary expressions with the / operator.
  2. Extracting type information from the left operand.
  3. Raising alerts if the type matches Milliseconds.

Dive deeper into typescript-eslint guidelines and type-aware rules at:

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

How do I extract a specific property from an array of objects and assign it to a new array in Typescript 2?

I've got this TypeScript 2 "model" that looks like this: export class MyModel { myProperty1: string; myProperty2: string; ... } In addition to the model, I have another class defined as follows: // Imports excluded for brevity @Component . ...

Is Highcharts-angular (Highcharts wrapper for Angular) compatible with Angular 4?

I have attempted to install various versions of highcharts-angular, ranging from 2.0.0 to 2.10.0. However, I consistently encounter the same error when running the application. The error message states: Metadata version mismatch for module C:/dev/Angular- ...

Finding the specific type within a union based on its field type

I am trying to implement a function sendCommand that returns a value of type specified by the union InputActions, selected based on the action_id type. Below is my code snippet: interface OutputAction1 { command: 'start', params: string; } i ...

Is it possible to access the line number of a node using the TypeScript compiler API?

Is there a method to retrieve the line number of a node besides using node.pos? For example, something like node.lineNumber? ...

Utilize Typescript compiler to identify mistakes during object property access using square brackets

Is it possible to configure the Typescript compiler to identify errors when accessing object properties using square brackets? I have inherited a codebase where object property access is predominantly done with square brackets (obj['myProp'] ins ...

The process of sorting through an array of objects based on their specific types in TypeScript

I am working on a function that filters an array of objects based on their type property: export const retrieveLayoutChangeActions = (data: GetOperations['included']) => data.filter(d => d.type === 'layoutChangeAction') as Layou ...

When setting a value that has been explicitly casted, the original literal type remains intact for the new property or variable

After defining the constant MODE with specific values, I noticed something interesting: const MODE = { NONE: 0 as 0, COMPLETED: 1 as 1, DELETED: 2 as 2 } as const // In a CreateReactApp project, enums aren't available It became appar ...

Invoke the function on a different module using a router

When I click a button on a table, my goal is to navigate to another component and trigger a specific element - in this case, calling the method GetReport. Is it possible to achieve this using Router or similar functionality? This scenario involves angula ...

Having trouble constructing Shopware 6 admin using npm version 8.11

Upon executing bin/build-administration.sh, the following error is encountered: npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5a3f2 ...

Tips for Achieving Observable Synchronization

I've encountered a coding challenge that has led me to this code snippet: ngOnInit(): void { this.categories = this.categoryService.getCategories(); var example = this.categories.flatMap((categor) => categor.map((categories) = ...

Update each row in Sequelize where an array within a JSONB object includes a specific string

I am currently working with PostgreSQL. I have a table called users that includes a column titled preferences of type JSONB. An example shape of this column is as follows: { pets: ['Cat', 'Dog', 'Goldfish'], cars: ['S ...

Learn how to reposition the mat-option easily

I have an angular app with an autocomplete field that I need to adjust the position of. I have consulted the official documentation under the method updatePosition, which states: "Updates the position of the autocomplete suggestion panel to ensure that it ...

NextJS middleware API receives an uploaded image file form, but the request is undefined

Currently, I'm utilizing NextJS to handle form data processing and database uploads, with a pit stop at the NextJS API middleware for image editing. pages/uploadImage.tsx This is the client-side code handler. ... async function handleImageUpload(imag ...

Encountering an Error with Tagged Template Literals in TypeScript

I'm attempting to utilize tagged template literals from ES5 with TypeScript, but it appears that TypeScript doesn't fully support it. Here is the code snippet I have: class TemplateLiterals { age: number = 24; name: 'Luke Skywalker ...

Extending a class with diverse types in Typescript: A guide

I have a class with multiple methods that deal with an entity referred to as "entity." class entity { entityName: string = ''; getList(): any[] { someAPI + this.entityName .... } getOne(): any{ } } Additionally, there are specifi ...

The imported package is not functioning properly within the project

I've recently developed a Typescript Package and I want to test it in an application before publishing it on NPM. The main file (index.ts) of the package is structured like this => import Builder from './core/builder'; export default ...

Guide on creating a generic type that depends on the arguments provided, specifically a union type

I am dealing with the following similar types: class ActionFoo { action: 'foo'; foo: string; } class ActionBar { action: 'bar'; bar: number; } In addition, I have some handler functions for each type of defined "action", such a ...

Eliminate the need for require statements in TypeScript-generated JavaScript files

I am working on a website project and utilizing TypeScript for development. While using the tsc compiler, I noticed that all my JavaScript code compiles correctly. However, when I include an import statement in my TypeScript files, it gets compiled into J ...

An issue has occurred with error code TS2688: The type definition file for 'jquery' cannot be located. [Angular Application] --

I am currently working on developing an Angular web application with a specific theme that requires the inclusion of CSS and JS files. Majority of the JS files needed are jquery plugins, so I made sure to install them using the following commands: npm i j ...

Looking to display parent and child elements from a JSON object using search functionality in JavaScript or Angular

I am trying to display both parent and child from a Nested JSON data structure. Below is a sample of the JSON data: [ { "name": "India", "children": [ { "name": "D ...