Vue-I18n多余属性检查:如何以jp.json为基准校验其他语言文件
如何基于基准JSON Schema校验多语言文件的多余属性?
现有多语言文件
jp.json
{ "hello": "こんにちは" }
ge.json
{ "hello": "hallo", "world": "welt" }
当前Vue-I18n初始化代码
import { createI18n } from 'vue-i18n' import jp from '@/i18n/jp.json' import ge from '@/i18n/ge.json' type Schema = typeof jp const i18n = createI18n<[Schema], 'jp' | 'ge', false>({ legacy: false, locale: 'jp', fallbackLocale: 'jp', messages: { jp, ge } })
问题
当前以jp.json为基准定义Schema类型,但TypeScript无法检测出ge.json中多余的"world"属性,需要实现对其他语言文件的校验,确保其结构严格匹配基准Schema,不能有多余属性。
解决方案
方法1:用TypeScript工具类型强制约束子集匹配
定义工具类型,确保其他语言文件的键完全包含在基准Schema中,无多余属性:
import { createI18n } from 'vue-i18n' import jp from '@/i18n/jp.json' import ge from '@/i18n/ge.json' // 基准Schema type BaseSchema = typeof jp // 工具类型:排除存在多余键的类型 type StrictlyMatches<T extends BaseSchema> = Exclude<keyof T, keyof BaseSchema> extends never ? T : never // 对ge文件进行类型校验,有多余属性会直接报错 const geStrict: StrictlyMatches<typeof ge> = ge const i18n = createI18n<[BaseSchema], 'jp' | 'ge', false>({ legacy: false, locale: 'jp', fallbackLocale: 'jp', messages: { jp, ge: geStrict } })
方法2:直接约束Messages的类型结构
在定义messages对象时,强制所有语言文件必须严格匹配基准Schema:
import { createI18n } from 'vue-i18n' import jp from '@/i18n/jp.json' import ge from '@/i18n/ge.json' type BaseSchema = typeof jp // 强制所有语言的message必须符合基准Schema type StrictMessages = Record<'jp' | 'ge', BaseSchema> // 此处若ge有多余属性,TypeScript会直接抛出错误 const messages: StrictMessages = { jp, ge } const i18n = createI18n<[BaseSchema], keyof StrictMessages, false>({ legacy: false, locale: 'jp', fallbackLocale: 'jp', messages })
方法3:用JSON Schema文件做全局校验(适合大型项目)
如果语言文件体积较大,可生成基准JSON Schema文件,让编辑器和TypeScript直接校验所有语言文件:
- 安装依赖:
npm install ts-json-schema-generator --save-dev
- 基于jp.json生成基准Schema:
npx ts-json-schema-generator --path ./src/i18n/jp.json --type BaseSchema --output ./src/i18n/base-schema.json
- 在
tsconfig.json中配置校验规则:
{ "compilerOptions": { // 其他编译配置 }, "include": ["src/**/*"], "jsonSchemaValidation": { "src/i18n/*.json": "./src/i18n/base-schema.json" } }
配置后,编辑器会实时提示JSON文件中的多余属性,TypeScript编译时也会报错。
内容的提问来源于stack exchange,提问作者Kromel
相关产品推荐
相关产品推荐

