i18next / i18next-parser

Parse your code to extract translation keys/values and manage your catalog files
MIT License
488 stars 199 forks source link

Allow ignoring typecheck-helper functions around Trans tag variables #863

Closed pxpeterxu closed 1 year ago

pxpeterxu commented 1 year ago

Why am I submitting this PR

Thanks again for maintaining this, @karellm!

This PR helps with extraction for React + Typescript + i18next projects that use a helper function to help with typechecking.

By default, for React with Typescript, components don't allow passing in objects as children. e.g., the below wouldn't typecheck:

const SomeComponent = (props) => (
  <Trans>Hello <b>{{ name: props.name }}</b></Trans>
);

i18next added a type option, allowObjectInHTMLChildren that helps with HTML elements. However, this still doesn't work for non-HTML components: e.g., the following would still not pass the typechecker.

const SomeComponent = (props) => (
  <Trans>Hello <Link to="/profile">{{ name: props.name }}</Link></Trans>
);

As a result, we (and some other teams we know) use either of the below methods:

// Option 1: already supported
const SomeComponent = (props) => (
  <Trans>Hello <Link to="/profile">{{ name: props.name } as any}</Link></Trans>
);

// Option 2
const SomeComponent = (props) => (
  <Trans>Hello <Link to="/profile">{{ name: props.name } as unknown as string}</Link></Trans>
);

// Option 3: slightly nicer because we can use a lint rule
// to make sure that castAsString() only appears in <Trans>
const SomeComponent = (props) => (
  <Trans>Hello <Link to="/profile">{castAsString({ name: props.name })}</Link></Trans>
);

function castAsString(obj: Record<string, unknown>): string {
  return obj as unknown as string;
}

However, right now, i18next-parser would not pick up { name: props.name } since it's in a function call or multiple levels of type-casts.

Changes

Does it fix an existing ticket?

No, but is somewhat related to #603

Checklist

codecov-commenter commented 1 year ago

Codecov Report

Patch coverage: 100.00% and project coverage change: +94.04 :tada:

Comparison is base (559d5bb) 0.00% compared to head (3f3b01b) 94.04%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #863 +/- ## =========================================== + Coverage 0 94.04% +94.04% =========================================== Files 0 11 +11 Lines 0 1830 +1830 =========================================== + Hits 0 1721 +1721 - Misses 0 109 +109 ``` | [Impacted Files](https://app.codecov.io/gh/i18next/i18next-parser/pull/863?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=i18next) | Coverage Δ | | |---|---|---| | [src/lexers/jsx-lexer.js](https://app.codecov.io/gh/i18next/i18next-parser/pull/863?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=i18next#diff-c3JjL2xleGVycy9qc3gtbGV4ZXIuanM=) | `98.45% <100.00%> (ø)` | | ... and [10 files with indirect coverage changes](https://app.codecov.io/gh/i18next/i18next-parser/pull/863/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=i18next)

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.

pxpeterxu commented 1 year ago

Whoops, sorry about that! I realized I'd added some other unneeded code in the README. I just added it back! @karellm take a look when you're free

karellm commented 1 year ago

Thanks! Deployed in 8.3.0