yaserso
yaserso

Reputation: 2868

How to augment typed npm module types?

I'm trying to augment the types in the iam-policies npm package.

Specifically, I am attempting to augment the ConditionKey type, or anything that will get me to the result that I want.

Here's what the types file for the package look like:

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 what my file iam-policies.d.ts looks like:

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 have errors such as "Duplicate Identifier 'ConditionBlock'", "Duplicate string index signature." and others that indicate data and expected in my conditionResolvers can't be of type Date. My tsconfig file is the same as the one found on the NestJS Typescript Starter.

What I want is to be able to augment the type of the parameters in the Resolver object and the type of. The ConditionResolver is a collection of functions.

Upvotes: 2

Views: 419

Answers (1)

yaserso
yaserso

Reputation: 2868

For anyone in the future, I augmented them through the following method:

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

declare module 'iam-policies' {
    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;

    interface NotActionBlock {
        notAction: Patterns;
    }

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

    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;
    }

    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 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 is not possible to change the types of a module, as a quick Google will confirm so. What I did was change the highter-level types, which were the classes, to achieve what I desired.

Upvotes: 1

Related Questions