diff --git a/types/vue-i18n/index.d.ts b/types/vue-i18n/index.d.ts new file mode 100644 index 0000000000..02174cb784 --- /dev/null +++ b/types/vue-i18n/index.d.ts @@ -0,0 +1,79 @@ +// Type definitions for vue-i18n 6.1 +// Project: https://github.com/kazupon/vue-i18n +// Definitions by: Kombu +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +import * as Vue from 'vue'; +import { PluginFunction } from 'vue'; + +declare namespace VueI18n { + type Path = string; + type Locale = string; + type Values = any[] | { [key: string]: any }; + type Choice = number; + type LocaleMessage = string | LocaleMessageObject | LocaleMessageArray; + interface LocaleMessageObject { [key: string]: LocaleMessage; } + interface LocaleMessageArray { [index: number]: LocaleMessage; } + interface LocaleMessages { [key: string]: LocaleMessageObject; } + type TranslateResult = string | LocaleMessageArray; + + interface Formatter { + format(message: string, values: Values): string; + } + + type MissingHandler = (locale: Locale, key: Path, vm?: Vue) => void; + + // tslint:disable-next-line:interface-name + interface I18nOptions { + locale?: Locale; + fallbackLocale?: Locale; + messages?: LocaleMessages; + formatter?: Formatter; + missing?: MissingHandler; + fallbackRoot?: boolean; + sync?: boolean; + silentTranslationWarn?: boolean; + } +} + +declare class VueI18n { + constructor(options?: VueI18n.I18nOptions) + + readonly messages: VueI18n.LocaleMessages; + + locale: VueI18n.Locale; + fallbackLocale: VueI18n.Locale; + missing: VueI18n.MissingHandler; + formatter: VueI18n.Formatter; + silentTranslationWarn: boolean; + + t(key: VueI18n.Path, values?: VueI18n.Values): VueI18n.TranslateResult; + t(key: VueI18n.Path, locale: VueI18n.Locale, values?: VueI18n.Values): VueI18n.TranslateResult; + tc(key: VueI18n.Path, choice?: VueI18n.Choice, values?: VueI18n.Values): string; + tc(key: VueI18n.Path, choice: VueI18n.Choice, locale: VueI18n.Locale, values?: VueI18n.Values): string; + te(key: VueI18n.Path, locale?: VueI18n.Locale): boolean; + + getLocaleMessage(locale: VueI18n.Locale): VueI18n.LocaleMessageObject; + setLocaleMessage(locale: VueI18n.Locale, message: VueI18n.LocaleMessageObject): void; + mergeLocaleMessage(locale: VueI18n.Locale, message: VueI18n.LocaleMessageObject): void; + + static install: PluginFunction; + static version: string; +} + +declare module 'vue/types/vue' { + interface Vue { + readonly $i18n: VueI18n; + $t: typeof VueI18n.prototype.t; + $tc: typeof VueI18n.prototype.tc; + $te: typeof VueI18n.prototype.te; + } +} + +declare module 'vue/types/options' { + interface ComponentOptions { + i18n?: VueI18n; + } +} + +export = VueI18n; diff --git a/types/vue-i18n/package.json b/types/vue-i18n/package.json new file mode 100644 index 0000000000..ca67af43b1 --- /dev/null +++ b/types/vue-i18n/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "vue": "^2.2.6" + } +} diff --git a/types/vue-i18n/tsconfig.json b/types/vue-i18n/tsconfig.json new file mode 100644 index 0000000000..cbff597b4f --- /dev/null +++ b/types/vue-i18n/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "vue-i18n-tests.ts" + ] +} diff --git a/types/vue-i18n/tslint.json b/types/vue-i18n/tslint.json new file mode 100644 index 0000000000..d88586e5bd --- /dev/null +++ b/types/vue-i18n/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +} diff --git a/types/vue-i18n/vue-i18n-tests.ts b/types/vue-i18n/vue-i18n-tests.ts new file mode 100644 index 0000000000..7ff9dab6e1 --- /dev/null +++ b/types/vue-i18n/vue-i18n-tests.ts @@ -0,0 +1,99 @@ +/// + +const assert = console.assert; +const random = () => Math.trunc(Math.exp(Math.log(Date.now()) * Math.random())); + +import * as Vue from 'vue'; +import * as VueI18n from 'vue-i18n'; +import { ComponentOptions } from 'vue'; + +/** + * VueI18n.install + */ +Vue.use(VueI18n); +VueI18n.install(Vue); + +/** + * VueI18n.version + */ +assert(typeof VueI18n.version === 'string'); + +/** + * VueI18n Instance + */ +const locale = random().toString(); +const key = `_${random()}`; +const value = `${random()}|${random()}|${random()}`; +const i18n = new VueI18n({ + locale, + fallbackLocale: locale, + messages: { + [locale]: { + [key]: value, + }, + }, + formatter: { + format(message, values) { + return message; + }, + }, + missing(locale, key, vm) { + }, + fallbackRoot: false, + sync: true, + silentTranslationWarn: true, +}); +assert(i18n.messages[locale][key] === value); +assert(i18n.locale === locale); +assert(i18n.fallbackLocale === locale); +assert(typeof i18n.missing === 'function'); +assert(typeof i18n.formatter.format === 'function'); +assert(i18n.silentTranslationWarn); +i18n.setLocaleMessage(locale, {}); +assert(i18n.getLocaleMessage(locale)[key] === undefined); +i18n.mergeLocaleMessage(locale, { [key]: value }); +assert(i18n.getLocaleMessage(locale)[key] === value); +assert(typeof i18n.t === 'function'); +assert(typeof i18n.tc === 'function'); +assert(typeof i18n.te === 'function'); + +/** + * Vue + */ +const vm = new Vue({ + i18n, +}); +assert(vm.$i18n === i18n); +assert(vm.$t(key) === value); +assert(vm.$t(key, ['', 0, false, null, undefined]) === value); +assert(vm.$t(key, { x: 'x' }) === value); +assert(vm.$t(key, locale) === value); +assert(vm.$t(key, locale, ['', 0, false, null, undefined]) === value); +assert(vm.$t(key, locale, { x: 'x' }) === value); +assert(vm.$tc(key) === value); +assert(vm.$tc(key, 1) === value.split('|')[1]); +assert(vm.$tc(key, 1, []) === value.split('|')[1]); +assert(vm.$tc(key, 1, {}) === value.split('|')[1]); +assert(vm.$tc(key, 1, locale) === value.split('|')[1]); +assert(vm.$tc(key, 1, locale, []) === value.split('|')[1]); +assert(vm.$tc(key, 1, locale, {}) === value.split('|')[1]); +assert(vm.$te(key)); +assert(vm.$te(key, locale)); + +/** + * VueI18n + */ +{ + let path: VueI18n.Path; + let locale: VueI18n.Locale; + let values: VueI18n.Values; + let choice: VueI18n.Choice; + let localeMessage: VueI18n.LocaleMessage; + let localeMessageObject: VueI18n.LocaleMessageObject; + let localeMessageArray: VueI18n.LocaleMessageArray; + let localeMessages: VueI18n.LocaleMessages; + let translateResult: VueI18n.TranslateResult; + let formatter: VueI18n.Formatter; + let missingHandler: VueI18n.MissingHandler; + let i18nOptions: VueI18n.I18nOptions; +}