From b8f5783c86ea0770c2b9113d417a03d6f34817e0 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sat, 28 Jun 2025 14:37:14 -0500 Subject: [PATCH 1/4] feat: adds support for new "selector" API --- TransWithoutContext.d.ts | 84 ++++++++- .../selector-custom-types/Trans.test.tsx | 117 ++++++++++++ .../TransWithoutContext.test.tsx | 173 ++++++++++++++++++ .../Translation.test.tsx | 38 ++++ .../selector-custom-types/i18next.d.ts | 47 +++++ .../selector-custom-types/tsconfig.json | 5 + .../useTranslation.test.ts | 117 ++++++++++++ 7 files changed, 572 insertions(+), 9 deletions(-) create mode 100644 test/typescript/selector-custom-types/Trans.test.tsx create mode 100644 test/typescript/selector-custom-types/TransWithoutContext.test.tsx create mode 100644 test/typescript/selector-custom-types/Translation.test.tsx create mode 100644 test/typescript/selector-custom-types/i18next.d.ts create mode 100644 test/typescript/selector-custom-types/tsconfig.json create mode 100644 test/typescript/selector-custom-types/useTranslation.test.ts diff --git a/TransWithoutContext.d.ts b/TransWithoutContext.d.ts index d8acd67f6..1d12611e2 100644 --- a/TransWithoutContext.d.ts +++ b/TransWithoutContext.d.ts @@ -1,40 +1,79 @@ -import type { i18n, ParseKeys, Namespace, TypeOptions, TOptions, TFunction } from 'i18next'; +import type { + i18n, + ApplyTarget, + ConstrainTarget, + GetSource, + ParseKeys, + Namespace, + SelectorFn, + TypeOptions, + TOptions, + TFunction, +} from 'i18next'; import * as React from 'react'; type _DefaultNamespace = TypeOptions['defaultNS']; +type _EnableSelector = TypeOptions['enableSelector']; type TransChild = React.ReactNode | Record; -export type TransProps< - Key extends ParseKeys, + +/** + * This type functionally replaces {@link TransProps}, and should replace it + * when cut over from the string-based to the selector API (tentatively v27). + * + * So if you depend on this type directly, just be aware that it will be renamed + * to `TransProps` in a future major version. + */ +interface TransPropsInterface< + Key, Ns extends Namespace = _DefaultNamespace, KPrefix = undefined, TContext extends string | undefined = undefined, TOpt extends TOptions & { context?: TContext } = { context: TContext }, - E = React.HTMLProps, -> = E & { +> { children?: TransChild | readonly TransChild[]; components?: readonly React.ReactElement[] | { readonly [tagName: string]: React.ReactElement }; count?: number; context?: TContext; defaults?: string; i18n?: i18n; - i18nKey?: Key | Key[]; + i18nKey?: Key; ns?: Ns; parent?: string | React.ComponentType | null; // used in React.createElement if not null tOptions?: TOpt; values?: {}; shouldUnescape?: boolean; t?: TFunction; -}; +} -export function Trans< +export type GetTransProps< + Target extends ConstrainTarget, Key extends ParseKeys, Ns extends Namespace = _DefaultNamespace, KPrefix = undefined, TContext extends string | undefined = undefined, TOpt extends TOptions & { context?: TContext } = { context: TContext }, E = React.HTMLProps, ->(props: TransProps): React.ReactElement; +> = E & + TransPropsInterface< + _EnableSelector extends true + ? SelectorFn, KPrefix>, ApplyTarget, TOpt> + : Key | Key[], + Ns, + KPrefix, + TContext, + TOpt + >; + +export declare function Trans< + Key extends ParseKeys, + const Ns extends Namespace = _DefaultNamespace, + KPrefix = undefined, + TContext extends string | undefined = undefined, + TOpt extends TOptions & { context?: TContext } = { context: TContext }, + E = React.HTMLProps, + Target extends ConstrainTarget = ConstrainTarget, +>(props: GetTransProps): React.ReactElement; export type ErrorCode = | 'NO_I18NEXT_INSTANCE' @@ -71,3 +110,30 @@ export type ErrorMeta = { * ``` */ export type ErrorArgs = readonly [string, ErrorMeta | undefined, ...any[]]; + +/** + * This type left here in case anyone in userland depends on it -- it's no longer used internally, + * and can/should be removed when we cut over to the selector API (tentatively v27) + */ +export type TransProps< + Key extends ParseKeys, + Ns extends Namespace = _DefaultNamespace, + KPrefix = undefined, + TContext extends string | undefined = undefined, + TOpt extends TOptions & { context?: TContext } = { context: TContext }, + E = React.HTMLProps, +> = E & { + children?: TransChild | readonly TransChild[]; + components?: readonly React.ReactElement[] | { readonly [tagName: string]: React.ReactElement }; + count?: number; + context?: TContext; + defaults?: string; + i18n?: i18n; + i18nKey?: Key | Key[]; + ns?: Ns; + parent?: string | React.ComponentType | null; // used in React.createElement if not null + tOptions?: TOpt; + values?: {}; + shouldUnescape?: boolean; + t?: TFunction; +}; diff --git a/test/typescript/selector-custom-types/Trans.test.tsx b/test/typescript/selector-custom-types/Trans.test.tsx new file mode 100644 index 000000000..8edb9279b --- /dev/null +++ b/test/typescript/selector-custom-types/Trans.test.tsx @@ -0,0 +1,117 @@ +import { describe, it, expectTypeOf } from 'vitest'; +import * as React from 'react'; +import { Trans, useTranslation } from 'react-i18next'; + +describe('', () => { + describe('default namespace', () => { + it('standard usage', () => { + (expectTypeOf($.foo).toMatchTypeOf<'foo'>, $.foo)} />; + }); + + it(`raises a TypeError given a key that doesn't exist`, () => { + // @ts-expect-error + $.Nope} />; + }); + }); + + describe('named namespace', () => { + it('standard usage', () => { + (expectTypeOf($.foo).toEqualTypeOf<'foo'>, $.foo)} />; + }); + + it(`raises a TypeError given a namespace that doesn't exist`, () => { + expectTypeOf>() + .toHaveProperty('ns') + .extract<'Nope'>() + // @ts-expect-error + .toMatchTypeOf<'Nope'>(); + }); + }); + + describe('array namespace', () => { + it('should work with array namespace', () => ( + <> + (expectTypeOf($.baz).toEqualTypeOf<'baz'>(), $.baz)} + /> + (expectTypeOf($.custom.bar).toEqualTypeOf<'bar'>(), $.custom.bar)} + /> + (expectTypeOf($.alternate.baz).toEqualTypeOf<'baz'>(), $.alternate.baz)} + /> + (expectTypeOf($.bar).toEqualTypeOf<'bar'>(), $.bar)} + /> + ( + expectTypeOf($.alternate.foobar.deep.deeper.deeeeeper).toEqualTypeOf<'foobar'>(), + $.alternate.foobar.deep.deeper.deeeeeper + )} + /> + + )); + + it(`raises a TypeError given a key that's not present inside any namespace`, () => { + // @ts-expect-error + $.alternate.baz} />; + // @ts-expect-error + $.custom.baz} />; + }); + }); + + describe('usage with `t` function', () => { + it('should work when providing `t` function', () => { + const { t } = useTranslation('alternate'); + (expectTypeOf($.foobar.barfoo).toEqualTypeOf<'barfoo'>(), $.foobar.barfoo)} + />; + }); + + it('should work when providing `t` function with a prefix', () => { + const { t } = useTranslation('alternate', { keyPrefix: 'foobar.deep' }); + ( + expectTypeOf($.deeper.deeeeeper).toEqualTypeOf<'foobar'>(), $.deeper.deeeeeper + )} + />; + }); + + it('raises a TypeError given a key-prefixed `t` function and an invalid key', () => { + const { t } = useTranslation('alternate', { keyPrefix: 'foobar.deep' }); + // @ts-expect-error + $.xxx} />; + }); + }); + + describe('interpolation', () => { + it('should work with text and interpolation', () => { + expectTypeOf(Trans).toBeCallableWith({ + children: <>foo {{ var: '' }}, + }); + }); + + it('should work with Interpolation in HTMLElement', () => { + expectTypeOf(Trans).toBeCallableWith({ + children: ( + <> + foo {{ var: '' }} + + ), + }); + }); + + it('should work with text and interpolation as children of an HTMLElement', () => { + expectTypeOf(Trans).toBeCallableWith({ + children: foo {{ var: '' }}, + }); + }); + }); +}); diff --git a/test/typescript/selector-custom-types/TransWithoutContext.test.tsx b/test/typescript/selector-custom-types/TransWithoutContext.test.tsx new file mode 100644 index 000000000..953e5953e --- /dev/null +++ b/test/typescript/selector-custom-types/TransWithoutContext.test.tsx @@ -0,0 +1,173 @@ +import { describe, it, expectTypeOf, assertType } from 'vitest'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Trans } from '../../../TransWithoutContext'; + +describe('', () => { + describe('default namespace', () => { + it('standard usage', () => { + $.foo}>foo; + }); + + it("raises a TypeError given a key that doesn't exist", () => { + expectTypeOf>() + .toHaveProperty('i18nKey') + .extract<'Nope'>() + // @ts-expect-error + .toMatchTypeOf<'Nope'>(); + }); + }); + + describe('named namespace', () => { + it('standard usage', () => { + $.foo}>; + }); + + it("raises a TypeError given a namespace that doesn't exist", () => { + expectTypeOf>() + .toHaveProperty('ns') + .extract<'Nope'>() + // @ts-expect-error + .toMatchTypeOf<'Nope'>(); + }); + }); + + describe('array namespace', () => { + it('should work with array namespace', () => { + $.baz} />; + $.custom.bar} />; + $.bar} />; + $.alternate.baz} />; + + /** + * TODO: figure out what to do about default/fallback values? + * + * Currently, `Trans` doesn't accept a 'defaultValue' prop, like the + * `t` function does. + * + * I could add that, or we could try something different -- wanted to get + * feedback on this before starting down any particular path + */ + // expectTypeOf(Trans).toBeCallableWith({ + // ns: ['alternate', 'custom'], + // i18nKey: ['alternate:baz', 'custom:bar'], + // }); + }); + + it('raises a TypeError given a key not present inside the current namespace', () => { + // @ts-expect-error + $.alternate.baz} />; + // @ts-expect-error + $.bar} />; + // @ts-expect-error + $.custom.bar} />; + // @ts-expect-error + $.baz} />; + }); + }); + + describe('usage with `t` function', () => { + it('should work when providing `t` function', () => { + const { t } = useTranslation('alternate'); + + $.foobar.barfoo}> + foo + ; + }); + + it('should work when providing `t` function with a prefix', () => { + const { t } = useTranslation('alternate', { keyPrefix: 'foobar.deep' }); + + $.deeper.deeeeeper}> + foo + ; + }); + + it('raises a TypeError given a `t` function with key prefix when the key is invalid', () => { + const { t } = useTranslation('alternate', { keyPrefix: 'foobar.deep' }); + + // @ts-expect-error + $.xxx}> + foo + ; + }); + }); + + describe('interpolation', () => { + it('should work with text and interpolation', () => { + expectTypeOf(Trans).toBeCallableWith({ + children: <>foo {{ var: '' }}, + }); + }); + + it('should work with Interpolation in HTMLElement', () => { + expectTypeOf(Trans).toBeCallableWith({ + children: ( + <> + foo {{ var: '' }} + + ), + }); + }); + + it('should work with text and interpolation as children of an HTMLElement', () => { + expectTypeOf(Trans).toBeCallableWith({ + children: foo {{ var: '' }}, + }); + }); + }); + + describe('usage with context', () => { + it('should work with default namespace', () => { + assertType( $.some} context="me" />); + }); + + it('raises a TypeError when context is invalid', () => { + // @ts-expect-error + assertType( $.some} context="one" />); + }); + + it('should work with `ns` prop', () => { + assertType( $.beverage} />); + }); + + it('raises a TypeError given a namespace when context is invalid', () => { + assertType( + // @ts-expect-error + $.beverage} context="strawberry" />, + ); + }); + + it('should work with default `t` function', () => { + const { t } = useTranslation(); + + assertType( $.some} context="me" />); + }); + + it('raises a TypeError given a defaut `t` function when context is invalid', () => { + // @ts-expect-error should + assertType( $.some} context="Test1222" />); + }); + + it('should work with custom `t` function', () => { + const { t } = useTranslation('context'); + + assertType( $.dessert} context="cake" />); + }); + + it('raises a TypeError given a custom `t` function when context is invalid', () => { + // @ts-expect-error + assertType(); + }); + + it('should work with `ns` prop and `count` prop', () => { + const { t } = useTranslation('plurals'); + assertType( $.foo} count={2} />); + }); + + it('should work with custom `t` function and `count` prop', () => { + const { t } = useTranslation('plurals'); + assertType( $.foo} count={2} />); + }); + }); +}); diff --git a/test/typescript/selector-custom-types/Translation.test.tsx b/test/typescript/selector-custom-types/Translation.test.tsx new file mode 100644 index 000000000..96657574c --- /dev/null +++ b/test/typescript/selector-custom-types/Translation.test.tsx @@ -0,0 +1,38 @@ +import { describe, it, expectTypeOf } from 'vitest'; +import { Translation } from 'react-i18next'; +import React from 'react'; + +describe('', () => { + it('should work with default namespace', () => ( + {(t) => t(($) => $.foo)} + )); + + it('should work with named default namespace', () => ( + {(t) => t(($) => $.foo)} + )); + + it('should work with named namespace', () => ( + {(t) => t(($) => $.baz)} + )); + + it('should work with namespace array', () => { + + {(t) => `${t(($) => $.baz)} ${t(($) => $.custom.foo)}`} + ; + }); + + it("raises a TypeError given a namespace that doesn't exist", () => { + // @ts-expect-error + {(t) => t.fake}; + }); + + it("raises a TypeError given a key that's not in the namespace", () => { + // @ts-expect-error + {(t) => t.fake}; + }); + + it("raises a TypeError given a key that's not in the namespace (with namespace as prefix)", () => { + // @ts-expect-error + {(t) => t.custom.fake}; + }); +}); diff --git a/test/typescript/selector-custom-types/i18next.d.ts b/test/typescript/selector-custom-types/i18next.d.ts new file mode 100644 index 000000000..1de47cf6a --- /dev/null +++ b/test/typescript/selector-custom-types/i18next.d.ts @@ -0,0 +1,47 @@ +import 'i18next'; + +declare module 'i18next' { + interface CustomTypeOptions { + defaultNS: 'custom'; + allowObjectInHTMLChildren: true; + enableSelector: true; + resources: { + custom: { + foo: 'foo'; + bar: 'bar'; + + some: 'some'; + some_me: 'some context'; + }; + + alternate: { + baz: 'baz'; + foobar: { + barfoo: 'barfoo'; + deep: { + deeper: { + deeeeeper: 'foobar'; + }; + }; + }; + }; + + plurals: { + foo_zero: 'foo'; + foo_one: 'foo'; + foo_two: 'foo'; + foo_many: 'foo'; + foo_other: 'foo'; + }; + + context: { + dessert_cake: 'a nice cake'; + dessert_muffin_one: 'a nice muffin'; + dessert_muffin_other: '{{count}} nice muffins'; + + beverage: 'beverage'; + beverage_beer: 'beer'; + }; + }; + } +} diff --git a/test/typescript/selector-custom-types/tsconfig.json b/test/typescript/selector-custom-types/tsconfig.json new file mode 100644 index 000000000..6c88073b9 --- /dev/null +++ b/test/typescript/selector-custom-types/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../tsconfig.json", + "include": ["./**/*"], + "exclude": [] +} diff --git a/test/typescript/selector-custom-types/useTranslation.test.ts b/test/typescript/selector-custom-types/useTranslation.test.ts new file mode 100644 index 000000000..054bf5407 --- /dev/null +++ b/test/typescript/selector-custom-types/useTranslation.test.ts @@ -0,0 +1,117 @@ +import { describe, it, expectTypeOf, assertType } from 'vitest'; +import { useTranslation } from 'react-i18next'; +import { TFunction, i18n } from 'i18next'; + +describe('useTranslation', () => { + it('should provide result with both object and array', () => { + const result = useTranslation(); + + expectTypeOf(result).toMatchTypeOf<[TFunction, i18n, boolean]>(); + expectTypeOf(result).toHaveProperty('ready').toBeBoolean(); + expectTypeOf(result).toHaveProperty('t').toBeFunction(); + expectTypeOf(result).toHaveProperty('i18n').toBeObject(); + }); + + describe('default namespace', () => { + it('should work with default namespace', () => { + const [t] = useTranslation(); + + expectTypeOf(t).toBeCallableWith(($) => $.foo); + }); + + it('should work with default named namespace', () => { + const [t] = useTranslation('custom'); + + expectTypeOf(t).toBeCallableWith(($) => $.bar); + }); + }); + + describe('named namespace', () => { + it('should work with named namespace', () => { + const [t] = useTranslation('alternate'); + + expectTypeOf(t).toBeCallableWith(($) => $.baz); + }); + + it(`raises a TypeError given a namespace that doesn't exist`, () => { + // @ts-expect-error + const [t] = useTranslation(($) => $.fake); + }); + + it(`raises a TypeError given a key that's not in the namespace`, () => { + const [t] = useTranslation('custom'); + // @ts-expect-error + assertType(t(($) => $.fake)); + }); + }); + + describe('namespace as array', () => { + it('should work with const namespaces', () => { + const [t] = useTranslation(['alternate', 'custom']); + + expectTypeOf(t(($) => $.baz)).toEqualTypeOf<'baz'>(); + expectTypeOf(t(($) => $.baz, { ns: 'alternate' })).toEqualTypeOf<'baz'>(); + expectTypeOf(t(($) => $.custom.foo)).toEqualTypeOf<'foo'>(); + expectTypeOf(t(($) => $.foo, { ns: 'custom' })).toEqualTypeOf<'foo'>(); + }); + + it('should work with const namespaces', () => { + const namespaces = ['alternate', 'custom'] as const; + const [t] = useTranslation(namespaces); + + expectTypeOf(t(($) => $.baz)).toEqualTypeOf<'baz'>(); + expectTypeOf(t(($) => $.baz, { ns: 'alternate' })).toEqualTypeOf<'baz'>(); + expectTypeOf(t(($) => $.custom.foo)).toEqualTypeOf<'foo'>(); + expectTypeOf(t(($) => $.foo, { ns: 'custom' })).toEqualTypeOf<'foo'>(); + }); + + it('raises a TypeError given an incorrect key', () => { + const [t] = useTranslation(['custom']); + // @ts-expect-error + assertType(t(($) => $.custom.fake)); + // @ts-expect-error + assertType(t(($) => $.fake, { ns: 'custom' })); + }); + }); + + describe('with `keyPrefix`', () => { + it('should provide top-level string keys', () => { + const [t] = useTranslation('alternate', { keyPrefix: 'foobar' }); + + expectTypeOf(t(($) => $.barfoo)).toEqualTypeOf<'barfoo'>(); + }); + + it('should work with deeper objects', () => { + const [t] = useTranslation('alternate', { keyPrefix: 'foobar.deep' }); + + expectTypeOf(t(($) => $.deeper, { returnObjects: true })).toEqualTypeOf<{ + deeeeeper: 'foobar'; + }>(); + expectTypeOf(t(($) => $.deeper.deeeeeper)).toEqualTypeOf<'foobar'>(); + }); + + it('raises a TypeError given an invalid keyPrefix', () => { + // @ts-expect-error + useTranslation('alternate', { keyPrefix: 'abc' }); + }); + + it('raises a TypeError given an invalid key', () => { + const [t] = useTranslation('alternate', { keyPrefix: 'foobar' }); + // @ts-expect-error + assertType(t('abc')); + }); + }); + + it('should work with json format v4 plurals', () => { + const [t] = useTranslation('plurals'); + + expectTypeOf(t(($) => $.foo, { count: 0 })).toEqualTypeOf<'foo'>(); + }); + + it('raises a TypeError when attempting to select a pluralized key with a specific pluralized suffix', () => { + const [t] = useTranslation('plurals'); + + // @ts-expect-error + expectTypeOf(t(($) => $.foo_one)).toEqualTypeOf<'foo'>(); + }); +}); From 0c9c15ab6420ead1b7c24fe955b877948ba40671 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sat, 28 Jun 2025 14:51:12 -0500 Subject: [PATCH 2/4] docs: clean up comments --- TransWithoutContext.d.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/TransWithoutContext.d.ts b/TransWithoutContext.d.ts index 1d12611e2..3ffbead34 100644 --- a/TransWithoutContext.d.ts +++ b/TransWithoutContext.d.ts @@ -18,11 +18,12 @@ type _EnableSelector = TypeOptions['enableSelector']; type TransChild = React.ReactNode | Record; /** - * This type functionally replaces {@link TransProps}, and should replace it - * when cut over from the string-based to the selector API (tentatively v27). + * This type functionally replaces {@link TransProps}, and should replace + * it when cut over from the string-based to the selector API + * (tentatively v27). * - * So if you depend on this type directly, just be aware that it will be renamed - * to `TransProps` in a future major version. + * So if you depend on this type directly, just be aware that it will be + * renamed to `TransProps` in a future major release. */ interface TransPropsInterface< Key, @@ -112,8 +113,9 @@ export type ErrorMeta = { export type ErrorArgs = readonly [string, ErrorMeta | undefined, ...any[]]; /** - * This type left here in case anyone in userland depends on it -- it's no longer used internally, - * and can/should be removed when we cut over to the selector API (tentatively v27) + * This type left here in case anyone in userland depends on it. + * It's no longer used internally, and can/should be removed when + * we cut over to the selector API (tentatively v27) */ export type TransProps< Key extends ParseKeys, From a69590d6c38aed198624e238c3205dbdc2391f7f Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sat, 28 Jun 2025 21:17:51 -0500 Subject: [PATCH 3/4] fix: broken test --- test/typescript/selector-custom-types/useTranslation.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/typescript/selector-custom-types/useTranslation.test.ts b/test/typescript/selector-custom-types/useTranslation.test.ts index 054bf5407..38f30faf9 100644 --- a/test/typescript/selector-custom-types/useTranslation.test.ts +++ b/test/typescript/selector-custom-types/useTranslation.test.ts @@ -35,7 +35,7 @@ describe('useTranslation', () => { it(`raises a TypeError given a namespace that doesn't exist`, () => { // @ts-expect-error - const [t] = useTranslation(($) => $.fake); + useTranslation('fake'); }); it(`raises a TypeError given a key that's not in the namespace`, () => { From 1b9d390627d2f5f6b22b01379c691155054b52a1 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 29 Jun 2025 16:56:49 -0500 Subject: [PATCH 4/4] fix: broken test --- test/typescript/selector-custom-types/Trans.test.tsx | 10 +++++++++- .../selector-custom-types/TransWithoutContext.test.tsx | 8 ++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/typescript/selector-custom-types/Trans.test.tsx b/test/typescript/selector-custom-types/Trans.test.tsx index 8edb9279b..b0d57c416 100644 --- a/test/typescript/selector-custom-types/Trans.test.tsx +++ b/test/typescript/selector-custom-types/Trans.test.tsx @@ -35,6 +35,10 @@ describe('', () => { ns={['alternate', 'custom']} i18nKey={($) => (expectTypeOf($.baz).toEqualTypeOf<'baz'>(), $.baz)} /> + (expectTypeOf($.alternate.baz).toEqualTypeOf<'baz'>(), $.baz)} + /> (expectTypeOf($.custom.bar).toEqualTypeOf<'bar'>(), $.custom.bar)} @@ -47,6 +51,10 @@ describe('', () => { ns={['custom', 'alternate']} i18nKey={($) => (expectTypeOf($.bar).toEqualTypeOf<'bar'>(), $.bar)} /> + (expectTypeOf($.custom.bar).toEqualTypeOf<'bar'>(), $.bar)} + /> ( @@ -59,7 +67,7 @@ describe('', () => { it(`raises a TypeError given a key that's not present inside any namespace`, () => { // @ts-expect-error - $.alternate.baz} />; + $.bar} />; // @ts-expect-error $.custom.baz} />; }); diff --git a/test/typescript/selector-custom-types/TransWithoutContext.test.tsx b/test/typescript/selector-custom-types/TransWithoutContext.test.tsx index 953e5953e..6aa496085 100644 --- a/test/typescript/selector-custom-types/TransWithoutContext.test.tsx +++ b/test/typescript/selector-custom-types/TransWithoutContext.test.tsx @@ -36,7 +36,9 @@ describe('', () => { it('should work with array namespace', () => { $.baz} />; $.custom.bar} />; + $.alternate.baz} />; $.bar} />; + $.custom.bar} />; $.alternate.baz} />; /** @@ -55,12 +57,6 @@ describe('', () => { }); it('raises a TypeError given a key not present inside the current namespace', () => { - // @ts-expect-error - $.alternate.baz} />; - // @ts-expect-error - $.bar} />; - // @ts-expect-error - $.custom.bar} />; // @ts-expect-error $.baz} />; });