Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.6.0] types not importable #774

Closed
Cielquan opened this issue Feb 8, 2023 · 6 comments
Closed

[7.6.0] types not importable #774

Cielquan opened this issue Feb 8, 2023 · 6 comments

Comments

@Cielquan
Copy link
Contributor

Cielquan commented Feb 8, 2023

馃悰 Bug Report

With #660 (release 7.0.0) a type definition file was added and with #694 (release 7.5.0) the file was added to the dist when building. Prior it was missing in the npm package.

I just updated to 7.6.0 and can verify that the types are installed in node_modules/i18next-parser/dist/index.d.ts. Unfortunately I cannot import them with import { UserConfig } from "i18next-parser"; inside i18next-parser.config.ts. I get the error that the file cannot be found.

I looked in some other packages installed in my node_modules and in most cases I can find a index.d.ts file in the package's root directory and not their dist directory. When I move the index.d.ts file of i18next-parser one directory up in it's root, I can import it with no issues.

I have 0 knowledge about packaging in the JS world, so I cannot comprehend where the real underlying issue is. Maybe I am just too unknowing in this department to correctly import them. But because all those other packages had their types in their root directory I think that's the way to go?

To Reproduce

  1. Install i18next-parser
  2. create i18next-parser.config.ts file
  3. add import { UserConfig } from "i18next-parser";
  4. see error

Expected behavior

The types should be importable without tinkering.

Your Environment

  • runtime version: node v18.10
  • i18next version: 22.4.9
  • os: Linux

Additional Information

I also had the import issue when I build my custom lexer (#678) to support shouldUnescape. I could not import the JsxLexer class and simply extend it. So I had to fully copy paste the BaseLexer, JavascriptLexer and JsxLexer source to add a couple lines of code.

Like stated above I don't know anything about packaging, but e.g. i18next-conv (repo) has a cli and I can import it to build custom scripts. They have a file in the bin/ directory and their source in a lib/ instead of dist/ directory and then export everything from a index.js file in the package root. Maybe this would be a solution here too?

EDIT: add additional info
EDIT2: add additional info
EDIT3: add additional info

@peksipatongeis
Copy link

package.json is missing the types property and it fails because the types were moved to the dist folder. Created a PR to add the missing types property to fix this.

@peksipatongeis
Copy link

Meanwhile I fixed the issue by creating a local type declaration i18next-parser.d.ts, just make sure it gets included by your tsconfig

declare module 'i18next-parser' {
  import EventEmitter from 'events';

  export type SupportedLexer = 'HandlebarsLexer' | 'HTMLLexer' | 'JavascriptLexer' | 'JsxLexer' | 'VueLexer';

  // BaseLexer is not importable therefore this is the best if done simple
  export class CustomLexerClass extends EventEmitter {}
  export type CustomLexer = typeof CustomLexerClass;

  export interface CustomLexerConfig extends Record<string, unknown> {
    lexer: CustomLexer;
  }

  export interface HandlebarsLexerConfig {
    lexer: 'HandlebarsLexer';
    functions?: string[];
  }

  export interface HTMLLexerConfig {
    lexer: 'HTMLLexer';
    functions?: string[];
    attr?: string;
    optionAttr?: string;
  }

  export interface JavascriptLexerConfig {
    lexer: 'JavascriptLexer';
    functions?: string[];
    namespaceFunctions?: string[];
    attr?: string;
    parseGenerics?: false;
    typeMap?: Record<string, unknown>;
  }

  export interface JavascriptWithTypesLexerConfig {
    lexer: 'JavascriptLexer';
    functions?: string[];
    namespaceFunctions?: string[];
    attr?: string;
    parseGenerics: true;
    typeMap: Record<string, unknown>;
  }

  export interface JsxLexerConfig {
    lexer: 'JsxLexer';
    functions?: string[];
    namespaceFunctions?: string[];
    attr?: string;
    transSupportBasicHtmlNodes?: boolean;
    transKeepBasicHtmlNodesFor?: string[];
    parseGenerics?: false;
    typeMap?: Record<string, unknown>;
  }

  export interface JsxWithTypesLexerConfig {
    lexer: 'JsxLexer';
    functions?: string[];
    namespaceFunctions?: string[];
    attr?: string;
    transSupportBasicHtmlNodes?: boolean;
    transKeepBasicHtmlNodesFor?: string[];
    parseGenerics: true;
    typeMap: Record<string, unknown>;
  }

  export interface VueLexerConfig {
    lexer: 'VueLexer';
    functions?: string[];
  }

  export type LexerConfig =
    | HandlebarsLexerConfig
    | HTMLLexerConfig
    | JavascriptLexerConfig
    | JavascriptWithTypesLexerConfig
    | JsxLexerConfig
    | JsxWithTypesLexerConfig
    | VueLexerConfig
    | CustomLexerConfig;

  export interface UserConfig {
    contextSeparator?: string;
    createOldCatalogs?: boolean;
    defaultNamespace?: string;
    defaultValue?: string | ((locale?: string, namespace?: string, key?: string) => string);
    indentation?: number;
    keepRemoved?: boolean;
    keySeparator?: string | false;
    lexers?: {
      hbs?: (SupportedLexer | CustomLexer | LexerConfig)[];
      handlebars?: (SupportedLexer | CustomLexer | LexerConfig)[];
      htm?: (SupportedLexer | CustomLexer | LexerConfig)[];
      html?: (SupportedLexer | CustomLexer | LexerConfig)[];
      mjs?: (SupportedLexer | CustomLexer | LexerConfig)[];
      js?: (SupportedLexer | CustomLexer | LexerConfig)[];
      ts?: (SupportedLexer | CustomLexer | LexerConfig)[];
      jsx?: (SupportedLexer | CustomLexer | LexerConfig)[];
      tsx?: (SupportedLexer | CustomLexer | LexerConfig)[];
      default?: (SupportedLexer | CustomLexer | LexerConfig)[];
    };
    lineEnding?: 'auto' | 'crlf' | '\r\n' | 'cr' | '\r' | 'lf' | '\n';
    locales?: string[];
    namespaceSeparator?: string | false;
    output?: string;
    pluralSeparator?: string;
    input?: string | string[];
    sort?: boolean | ((a: string, b: string) => -1 | 0 | 1);
    skipDefaultValues?: boolean | ((locale?: string, namespace?: string) => boolean);
    useKeysAsDefaultValue?: boolean | ((locale?: string, namespace?: string) => boolean);
    verbose?: boolean;
    failOnWarnings?: boolean;
    failOnUpdate?: boolean;
    customValueTemplate?: Record<string, string> | null;
    resetDefaultValueLocale?: string | null;
    i18nextOptions?: Record<string, unknown> | null;
    yamlOptions?: Record<string, unknown> | null;
  }
}

@Cielquan
Copy link
Contributor Author

Thanks for the idea. I already have a local type declaration file. The file included in i18next-parser is originally made by me (#660).

I wanted to remove the local file to reduce the file count, but after your PR is merged and released I will be able to do that. Thanks again for your fix.

@karellm
Copy link
Member

karellm commented Feb 18, 2023

Should be fixed as of 7.7.0

@karellm karellm closed this as completed Feb 18, 2023
@Cielquan
Copy link
Contributor Author

I just updated to 7.7 and can confirm that the issue is solved.

@landabaso
Copy link

Isn't it missing declarations for parser, gulp, broccoli and transform? I was trying to use i18next-parser as an API using typescript and it won't let you import any of those because declarations are missing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants