metadevpro / openapi3-ts

TS Model & utils for creating and exposing OpenAPI 3.x contracts.
MIT License
492 stars 64 forks source link

No index signature with a parameter of type 'string' was found on type 'ISpecificationExtension'. #105

Closed BryanHunt closed 1 year ago

BryanHunt commented 1 year ago

We are trying to update to 4.0.2 and our builds are broken with the following errors after changing my imports as documented.

Changed import to:

import { MediaTypeObject } from 'openapi3-ts/src/model/openapi31';

I get:

node_modules/openapi3-ts/src/model/oas-common.ts:21:16 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ISpecificationExtension'.
  No index signature with a parameter of type 'string' was found on type 'ISpecificationExtension'.

21         return obj[extensionName];
                  ~~~~~~~~~~~~~~~~~~

node_modules/openapi3-ts/src/model/oas-common.ts:31:9 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ISpecificationExtension'.
  No index signature with a parameter of type 'string' was found on type 'ISpecificationExtension'.

31         obj[extensionName] = extension;
           ~~~~~~~~~~~~~~~~~~

node_modules/openapi3-ts/src/model/specification-extension.ts:28:13 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'SpecificationExtension'.
  No index signature with a parameter of type 'string' was found on type 'SpecificationExtension'.

28         if (this[extensionName]) {
               ~~~~~~~~~~~~~~~~~~~

node_modules/openapi3-ts/src/model/specification-extension.ts:29:20 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'SpecificationExtension'.
  No index signature with a parameter of type 'string' was found on type 'SpecificationExtension'.

29             return this[extensionName];
                      ~~~~~~~~~~~~~~~~~~~

node_modules/openapi3-ts/src/model/specification-extension.ts:39:9 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'SpecificationExtension'.
  No index signature with a parameter of type 'string' was found on type 'SpecificationExtension'.

39         this[extensionName] = payload;
           ~~~~~~~~~~~~~~~~~~~
pjmolina commented 1 year ago

Hi @BryanHunt
Please note we needed to change the way classes are exported, see #104 to check the changes you need to do in your imports.

BryanHunt commented 1 year ago

I did change my imports. This is what I'm using now ...

import { MediaTypeObject } from 'openapi3-ts/src/model/openapi31';

Am I missing something else?

pjmolina commented 1 year ago

If you don't have additional import errors it will be fine.

BryanHunt commented 1 year ago

Sorry, I'm not following. What will be fine?

pjmolina commented 1 year ago

I meant, if there are no more import errors, its complete. You don't need to change anything else.

BryanHunt commented 1 year ago

With that import in my comment above, I get the build failure that I originally reported.

BryanHunt commented 1 year ago

Updated the original comment to make this more clear.

pjmolina commented 1 year ago

Ok. I see. Extension names are now checked to be starting with the prefix x- (per the spec)

See: specification-extension.ts

export type IExtensionName = `x-${string}`;
export type IExtensionType = any;
export type ISpecificationExtension = {
    [extensionName: IExtensionName]: IExtensionType;
};

If you need to force the types to bypass the check, you can do:

    return obj[extensionName as IExtensionName]; 

Or use the static methods to retrieve and set the extensions:

export class SpecificationExtension implements ISpecificationExtension {
    [extensionName: IExtensionName]: any;

    static isValidExtension(extensionName: string): boolean {
        return /^x-/.test(extensionName);
    }

    getExtension(extensionName: string): any {
        if (!SpecificationExtension.isValidExtension(extensionName)) {
            throw new Error(
                `Invalid specification extension: '${extensionName}'. Extensions must start with prefix 'x-`
            );
        }
        if (this[extensionName]) {
            return this[extensionName];
        }
        return null;
    }
    addExtension(extensionName: string, payload: any): void {
        if (!SpecificationExtension.isValidExtension(extensionName)) {
            throw new Error(
                `Invalid specification extension: '${extensionName}'. Extensions must start with prefix 'x-`
            );
        }
        this[extensionName] = payload;
    }
...
BryanHunt commented 1 year ago

I'm not using extensions. One of my modules that fails to build is using these two exact imports:

import { MediaTypeObject } from 'openapi3-ts/src/model/openapi31';
import { SecuritySchemeObject } from 'openapi3-ts/src/model/openapi31';
pjmolina commented 1 year ago

Ok. What version of typescript are you using? tsc --version

Can you verify it with v. 5.0.2

Looks like https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html is a new feature of the tsc compiler, introduced from TS 4.1

BryanHunt commented 1 year ago

We are using 5.0.2

pjmolina commented 1 year ago

Can you share a minimal repro sample? I will try to debug and diagnose.

BryanHunt commented 1 year ago

I'll see if I can put something together.

BryanHunt commented 1 year ago

https://github.com/BryanHunt/openapi-test

pjmolina commented 1 year ago

Thank you very much for the sample @BryanHunt

Root cause The difference is in the setting in tsconfig.json:

When importing the sources, the errors appears only in your side given the configuration. I am going to prepare a fix in the lib making tsconfig.json more strict.

pjmolina commented 1 year ago

Package publishing is now down on npmjs. I will publish v. 4.0.3 with the fix in #106 as soon as is back to live again.

pjmolina commented 1 year ago

Published as https://www.npmjs.com/package/openapi3-ts/v/4.0.3 Feel free to reopen the issue if you detect any other problem. Thanks @BryanHunt

BryanHunt commented 1 year ago

My builds are fixed. Thanks the the quick response.