From 6a244bc38d9ebba28c74a6e825036ad89c71a9f6 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Thu, 30 Jan 2025 14:44:50 +0100 Subject: [PATCH] feat: configurable custom property `$i18n` type --- packages/vue-i18n-core/src/index.ts | 7 ++++- packages/vue-i18n-core/src/types.ts | 43 +++++++++++++++++++++++++++++ packages/vue-i18n/src/index.ts | 2 +- packages/vue-i18n/src/vue.d.ts | 5 ++-- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/packages/vue-i18n-core/src/index.ts b/packages/vue-i18n-core/src/index.ts index 65f3c72d2..13f90cd87 100644 --- a/packages/vue-i18n-core/src/index.ts +++ b/packages/vue-i18n-core/src/index.ts @@ -106,7 +106,12 @@ export { } from './legacy' export { VERSION } from './misc' export { I18nPluginOptions } from './plugin' -export { Disposer } from './types' +export { + Disposer, + GeneratedInstanceType, + GeneratedTypeConfig, + VueI18nInstance +} from './types' export type { IsEmptyObject, diff --git a/packages/vue-i18n-core/src/types.ts b/packages/vue-i18n-core/src/types.ts index 7bb1de228..d226bc21f 100644 --- a/packages/vue-i18n-core/src/types.ts +++ b/packages/vue-i18n-core/src/types.ts @@ -1 +1,44 @@ +import type { IsNever } from '@intlify/core-base' +import type { ExportedGlobalComposer } from './i18n' +import type { VueI18n } from './legacy' + export type Disposer = () => void + +/** + * + * The interface used for narrowing types using generated types. + * + * @remarks + * + * The type generated by 3rd party (e.g. nuxt/i18n) + * + * @example + * ```ts + * // generated-i18n-types.d.ts (`.d.ts` file at your app) + * + * declare module '@intlify/vue-i18n-core' { + * interface GeneratedTypeConfig { + * legacy: false + * } + * } + * ``` + */ +export interface GeneratedTypeConfig {} + +/** + * Narrowed i18n instance type based on `GeneratedTypeConfig['legacy']` + * + * - `never` (unset) resolves to `VueI18n | ExportedGlobalComposer` + * - `true` resolves to `VueI18n` + * - `false` resolves to `ExportedGlobalComposer` + */ +export type GeneratedInstanceType = + GeneratedTypeConfig extends Record<'legacy', infer Legacy> ? Legacy : never + +/** @VueI18nGeneral */ +export type VueI18nInstance = + IsNever extends true + ? VueI18n | ExportedGlobalComposer + : GeneratedInstanceType extends true + ? VueI18n + : ExportedGlobalComposer diff --git a/packages/vue-i18n/src/index.ts b/packages/vue-i18n/src/index.ts index c9b97463c..1a948ab11 100644 --- a/packages/vue-i18n/src/index.ts +++ b/packages/vue-i18n/src/index.ts @@ -125,7 +125,7 @@ export { } from '../../vue-i18n-core/src/legacy' export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin' export { VERSION } from './../../vue-i18n-core/src/misc' -export { Disposer } from './../../vue-i18n-core/src/types' +export { Disposer, VueI18nInstance } from './../../vue-i18n-core/src/types' export type { IsEmptyObject, diff --git a/packages/vue-i18n/src/vue.d.ts b/packages/vue-i18n/src/vue.d.ts index adee667c2..25d5f7059 100644 --- a/packages/vue-i18n/src/vue.d.ts +++ b/packages/vue-i18n/src/vue.d.ts @@ -21,14 +21,13 @@ import type { DefineDateTimeFormat, DefineLocaleMessage, RemovedIndexResources, + VueI18nInstance, VueMessageType } from '../../vue-i18n-core/src/composer' -import type { ExportedGlobalComposer } from '../../vue-i18n-core/src/i18n' import type { DateTimeFormatResult, NumberFormatResult, TranslateResult, - VueI18n, VueI18nOptions } from '../../vue-i18n-core/src/legacy' @@ -74,7 +73,7 @@ declare module 'vue' { * The locales, locale messages, and other resources managed by the instance referenced by this property are valid as global scope. * If the `i18n` component custom option is not specified, it's the same as the VueI18n instance that can be referenced by the i18n instance {@link I18n.global | global} property. */ - $i18n: VueI18n | ExportedGlobalComposer + $i18n: VueI18nInstance /** * Locale message translation *