Increasing typed npm module types: a guide

I am currently working on enhancing the data types within the iam-policies npm package.

My main focus is on augmenting the ConditionKey type, or any other approach that can help me achieve the desired outcome.

Take a look at the types file of the package:

export declare type ConditionKey = string | number | boolean;
...
declare type Resolver = (data: ConditionKey, expected: ConditionKey) => boolean;
export interface ConditionResolver {
    [key: string]: Resolver;
}
export interface Context {
    [key: string]: ConditionKey | Context | string[] | number[];
}

Here's the content of my file iam-policies.d.ts:

import { conditionResolvers }         from './conditions';
import { ConditionMap, ConditionKey } from 'iam-policies/dist/src/types';

declare module 'iam-policies/dist/src/types' {
    type Resolver = (data: any, expected: any) => boolean;

    type ConditionResolver = {
        [key in keyof typeof conditionResolvers]?: Resolver
    }

export interface Context {
    [key: string]: any;
}

}

I am encountering errors such as "Duplicate Identifier 'ConditionBlock'", "Duplicate string index signature." and others indicating that the 'data' and 'expected' parameters in my conditionResolvers cannot be of type 'Date'. The tsconfig file I am using is similar to the one provided in the NestJS Typescript Starter.

My goal is to enhance the type of parameters in the Resolver object and the overall type structure. The ConditionResolver represents a collection of functions.

Answer №1

In preparation for future users, I enhanced the functionality through the method outlined below:

// Library Imports
import { EffectBlock, ActionBlock, ResourceBlock, NotResourceBlock, Patterns } from 'iam-policies/dist/src/types';
// Application Imports
import { conditionResolvers }                                                                     from './iam/conditions';

declare module 'iam-policies' {
    // Customization of ConditionMap
    interface ConditionMap {
        [key: string]: any;
    }

    type ConditionBlock = {
        [key in keyof typeof conditionResolvers]?: ConditionMap;
    }

    interface StatementInterface {
        sid?: string;
        effect?: EffectBlock;
        condition?: ConditionBlock;
    }

    type ConditionResolver = typeof conditionResolvers;

    // Definition of IdentityBasedType
    type IdentityBasedType = StatementInterface & (ActionBlock | NotActionBlock) & (ResourceBlock | NotResourceBlock);
    export interface Context {
        [key: string]: any;
    }
    export interface EvaluateIdentityBasedInterface {
        action: string;
        resource: string;
        context?: Context;
    }

    // Class Implementation for IdentityBasedPolicy
    class IdentityBasedPolicy {
        constructor(config: IdentityBasedType[], conditionResolver?: ConditionResolver);
        evaluate({ action, resource, context, }: EvaluateIdentityBasedInterface): boolean;
        can({ action, resource, context }: EvaluateIdentityBasedInterface): boolean;
        cannot({ action, resource, context, }: EvaluateIdentityBasedInterface): boolean;
    }

    // Definition of PrincipalMap and ResourceBasedType
    type PrincipalMap = {
        [key in EEntityPolicyEnumPrincipal]?: EClient | EClient[] | string | string[];
    }
    interface PrincipalBlock {
        principal: PrincipalMap | Patterns;
    }
    interface NotPrincipalBlock {
        principal: PrincipalMap | Patterns;
    }

    type ResourceBasedType = StatementInterface & (PrincipalBlock | NotPrincipalBlock) & (ActionBlock | NotActionBlock) & (ResourceBlock | NotResourceBlock | {});

    export interface EvaluateResourceBasedInterface extends EvaluateIdentityBasedInterface {
        principal: string;
        principalType?: string;
    }

    // Class Implementation for ResourceBasedPolicy
    class ResourceBasedPolicy {
        constructor(config: ResourceBasedType[], conditionResolver?: ConditionResolver);
        evaluate({ principal, action, resource, principalType, context, }: EvaluateResourceBasedInterface): boolean;
        can({ principal, action, resource, principalType, context, }: EvaluateResourceBasedInterface): boolean;
        cannot({ principal, action, resource, principalType, context, }: EvaluateResourceBasedInterface): boolean;
    }
}

It's important to note that modifying the types of a module directly is not feasible, as confirmed by a quick search. Instead, I adjusted the higher-level types, specifically the classes, to align with my requirements.

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

What is the best way to create a method that waits for a POST request to complete?

I have the following code snippet: login() { const body = JSON.stringify({ "usuario":"juanma", "password":"1234"}); console.log(body); let tokencito:string = '' const params = ne ...

Avoiding Overload Conflicts: TypeScript and the Power of Generic Methods

I have created an interface type as follows: interface Input<TOutput> { } And then extended that interface with the following: interface ExampleInput extends Input<ExampleOutput> { } interface ExampleOutput { } Additionally, I ha ...

Error: The function cannot be executed on an immutable object in React Native Jest unit testing with Typescript

Currently, I am experimenting with jest unit testing for a typescript-based react native project. However, I am facing an issue when I run npm test, and the error message is as follows: ● Test suite failed to run TypeError: seamless_immutable_1.default ...

Double-executing methods in a component

I have encountered an issue while trying to filter existing Worklog objects and summarize the time spent on each one in my PeriodViewTable component. The problem I am facing involves duplicate method calls. To address this, I attempted to reset the value ...

How can React with TypeScript dynamically extend type definitions based on component props?

Can a React component dynamically determine which props it has? For example: type BaseType = { baseProp?: ... as?: ... } type Extended = { extendedProp?: ... } <Base /> // expected props => { baseProp } <Base as={ExtendedComponent} ...

The Crimson Thread when incorporating tsx into Next.js

https://i.sstatic.net/zXvPT.png While working with TSX in React and TypeScript, I encountered an issue. A red line appeared on the screen even though the project runs successfully. Can anyone explain why this red line is appearing and why the classes in T ...

Error encountered during execution of Angular application, specifically TS2305 error?

Hello, I am currently running an angular application by using the 'ng serve' command. I encountered the following error: ERROR in src/app/accounts/account-form/account-form.component.ts(29,3): error TS2305: Module '"/home/prasanth/primecas ...

Assign the private members of the class to the arguments of the constructor

class Bar { #one #two #three #four #five #six #seven #eight #nine #ten #eleven #twelve #thirteen #fourteen #fifteen #sixteen constructor( one, two, three, four, five, six, seven, eight, ...

Utilizing type maps within nested objects in Typescript: A comprehensive guide

Initially, a type is established that connects enum keys with specific types: enum MyEnum { A, B } type TypeMap = { [MyEnum.A]:string, [MyEnum.B]:number } interface ObjInterface<T extends keyof TypeMap> { obj: T, objData: Ty ...

Utilizing an Observable in an Angular 6 service to ensure proper synchronization with Okta token present in local storage

Within my application, I have implemented third-party authentication to facilitate user login and store a token in their local storage. To enhance the user experience, I am developing a service to cache profile information. This service utilizes the user&a ...

Upgrade your AngularJS Directive to an Angular 2.x+ Directive by using an HTML decorator

Is it no longer possible to utilize Angular directives as what I like to refer to as "HTML decorators"? I found this method extremely useful in Angular 1.x when transitioning legacy applications to Single Page Apps by creating a set of directives to enhan ...

Prevent selection of items in ng-select. Modifying the default item selection behavior in ng-select

In my code, I am utilizing an angular-multiselect component to upload a list of items and populate the [data] variable of the angular-multiselect. This component displays the list of data with checkboxes, allowing me to select all, search, and perform vari ...

Should private members be kept confidential during program execution?

While Typescript's "private" members may not be truly private at runtime, traditional closures maintain the privacy of their members. Is there value in ensuring that private members remain private during runtime? ...

The specified 'Promise<Modules>' type argument cannot be assigned to the parameter of type '(params: any) => Promise<Modules>' in the current context

Looking for some help with this helper function that I need to call, it has the following signature: export const fetchPaginated = async <T>( callback: (params: any) => Promise<T>, { page = 1, pageSize, }: { page?: number; page ...

Exploring TypeORM: Leveraging the In() function within @ManyToMany relationships

There are two main characters in my story: Hero and Villain (their profiles are provided below). How can I utilize the Encounter() method to identify all instances where the Hero interacts with the Villain based on an array of Villain IDs? I am seeking a ...

Utilizing an object as a prop within React-router's Link functionality

Looking for a solution to pass the entire product object from ProductList component to Product component. Currently, I am passing the id as a route param and fetching the product object again in the Product component. However, I want to directly send the ...

Creating fixtures with Playwright is a simple process that can greatly enhance

I have a requirement to set up fixtures where the first fixture is always available (acting as a base class) and the second fixture will vary in different test files (like a derived class). I've implemented the following code which seems to be working ...

Passing the user input from a textbox to a directive's input string in Angular 9 using Typescript

Is it possible to transfer the value entered in a textbox to another directive's input variable without utilizing ngModel? I am curious about how this can be accomplished. Here is the code snippet: HTML : <input type="text" placeholder= ...

Enhancing external TypeScript modules

Currently, I am delving into the realm of enhancing external modules in TypeScript. I am diligently studying the official documentation and the DefinitelyTyped guides, poring over examples, and so forth. At this point, my goal is to incorporate custom prop ...

What is the best way to extract the primary base64 value from reader.result?

After successfully retrieving the base64 value of my file, I noticed that along with the value, I am also getting the type of file and the type of string. However, I only require the actual value in order to send it to the backend. Code for converting fil ...