diff --git a/packages/vue-i18n-core/src/composer.ts b/packages/vue-i18n-core/src/composer.ts index bcafd5a0e..d4b61ba97 100644 --- a/packages/vue-i18n-core/src/composer.ts +++ b/packages/vue-i18n-core/src/composer.ts @@ -34,7 +34,9 @@ import { setAdditionalMeta, getFallbackContext, setFallbackContext, - DEFAULT_LOCALE + DEFAULT_LOCALE, + isMessageAST, + isMessageFunction } from '@intlify/core-base' import { VueDevToolsTimelineEvents } from '@intlify/vue-devtools' import { I18nWarnCodes, getWarnMessage } from './warnings' @@ -108,7 +110,8 @@ import type { RemoveIndexSignature, RemovedIndexResources, IsNever, - IsEmptyObject + IsEmptyObject, + CoreMissingType } from '@intlify/core-base' import type { VueDevToolsEmitter } from '@intlify/vue-devtools' import { isLegacyVueI18n } from './utils' @@ -1757,7 +1760,9 @@ export interface ComposerInternal { __setPluralRules(rules: PluralizationRules): void } -type ComposerWarnType = 'translate' | 'number format' | 'datetime format' +type ComposerWarnType = CoreMissingType + +const NOOP_RETURN_ARRAY = () => [] let composerID = 0 @@ -2309,7 +2314,7 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any { 'number format', // eslint-disable-next-line @typescript-eslint/no-explicit-any root => (root as any)[NumberPartsSymbol](...args), - () => [], + NOOP_RETURN_ARRAY, val => isString(val) || isArray(val) ) } @@ -2324,7 +2329,7 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any { 'datetime format', // eslint-disable-next-line @typescript-eslint/no-explicit-any root => (root as any)[DatetimePartsSymbol](...args), - () => [], + NOOP_RETURN_ARRAY, val => isString(val) || isArray(val) ) } @@ -2336,10 +2341,17 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any { // te function te(key: Path, locale?: Locale): boolean { - if (!key) return false + if (!key) { + return false + } const targetLocale = isString(locale) ? locale : _locale.value const message = getLocaleMessage(targetLocale) - return isString(_context.messageResolver(message, key)) + const resolved = _context.messageResolver(message, key) + return ( + isMessageAST(resolved) || + isMessageFunction(resolved) || + isString(resolved) + ) } function resolveMessages(key: Path): LocaleMessageValue | null { diff --git a/packages/vue-i18n-core/test/issues.test.ts b/packages/vue-i18n-core/test/issues.test.ts index 9451bd05d..84768c570 100644 --- a/packages/vue-i18n-core/test/issues.test.ts +++ b/packages/vue-i18n-core/test/issues.test.ts @@ -1197,3 +1197,33 @@ test('issue #1595 merge case', async () => { '
シンプル ディープ' ) }) + +test('issue #1610 merge case', async () => { + const en = { + hello: 'Hello, Vue I18n', + language: 'Languages' + } + const i18n = createI18n({ + legacy: false, + locale: 'en', + globalInjection: true, + messages: { + en: {} + } + }) + + const App = defineComponent({ + template: ` +

{{ $t('hello') }}

+{{ $te('hello') }} (...but this should be true) +` + }) + const wrapper = await mount(App, i18n) + + i18n.global.setLocaleMessage('en', en) + await nextTick() + + expect(wrapper.html()).include( + `

Hello, Vue I18n

true (...but this should be true)` + ) +})