chore(translations): enable TypeScript strict mode (#11494)
This commit is contained in:
@@ -150,7 +150,9 @@ export const importDateFNSLocale = async (locale: string): Promise<Locale> => {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.default) {
|
// @ts-expect-error - I'm not sure if this is still necessary.
|
||||||
|
if (result?.default) {
|
||||||
|
// @ts-expect-error - I'm not sure if this is still necessary.
|
||||||
return result.default
|
return result.default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
|
||||||
export function copyFile(source, destination) {
|
export function copyFile(source: string, destination: string) {
|
||||||
fs.copyFile(source, destination, (err) => {
|
fs.copyFile(source, destination, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// Handle error
|
// Handle error
|
||||||
|
|||||||
@@ -13,9 +13,12 @@ export function deepMergeSimple<T = object>(obj1: object, obj2: object): T {
|
|||||||
|
|
||||||
for (const key in obj2) {
|
for (const key in obj2) {
|
||||||
if (Object.prototype.hasOwnProperty.call(obj2, key)) {
|
if (Object.prototype.hasOwnProperty.call(obj2, key)) {
|
||||||
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||||
if (typeof obj2[key] === 'object' && !Array.isArray(obj2[key]) && obj1[key]) {
|
if (typeof obj2[key] === 'object' && !Array.isArray(obj2[key]) && obj1[key]) {
|
||||||
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||||
output[key] = deepMergeSimple(obj1[key], obj2[key])
|
output[key] = deepMergeSimple(obj1[key], obj2[key])
|
||||||
} else {
|
} else {
|
||||||
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||||
output[key] = obj2[key]
|
output[key] = obj2[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
|
||||||
export function ensureDirectoryExists(directory) {
|
export function ensureDirectoryExists(directory: string) {
|
||||||
try {
|
try {
|
||||||
if (!fs.existsSync(directory)) {
|
if (!fs.existsSync(directory)) {
|
||||||
fs.mkdirSync(directory, { recursive: true })
|
fs.mkdirSync(directory, { recursive: true })
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error creating directory '${directory}': ${error.message}`)
|
const msg = error instanceof Error ? error.message : 'Unknown error'
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(`Error creating directory '${directory}': ${msg}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ export const getTranslation = <T extends LabelType>(
|
|||||||
): T extends JSX.Element ? JSX.Element : string => {
|
): T extends JSX.Element ? JSX.Element : string => {
|
||||||
// If it's a Record, look for translation. If string or React Element, pass through
|
// If it's a Record, look for translation. If string or React Element, pass through
|
||||||
if (typeof label === 'object' && !Object.prototype.hasOwnProperty.call(label, '$$typeof')) {
|
if (typeof label === 'object' && !Object.prototype.hasOwnProperty.call(label, '$$typeof')) {
|
||||||
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||||
if (label[i18n.language]) {
|
if (label[i18n.language]) {
|
||||||
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||||
return label[i18n.language]
|
return label[i18n.language]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,8 +27,9 @@ export const getTranslation = <T extends LabelType>(
|
|||||||
fallbacks = i18n.fallbackLanguage
|
fallbacks = i18n.fallbackLanguage
|
||||||
}
|
}
|
||||||
|
|
||||||
const fallbackLang = fallbacks.find((language) => label[language])
|
const fallbackLang = fallbacks.find((language) => label[language as keyof typeof label])
|
||||||
|
|
||||||
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||||
return fallbackLang && label[fallbackLang] ? label[fallbackLang] : label[Object.keys(label)[0]]
|
return fallbackLang && label[fallbackLang] ? label[fallbackLang] : label[Object.keys(label)[0]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import type { Language } from '../types.js'
|
|||||||
|
|
||||||
import { clientTranslationKeys } from '../clientKeys.js'
|
import { clientTranslationKeys } from '../clientKeys.js'
|
||||||
|
|
||||||
function filterKeys(obj, parentGroupKey = '', keys) {
|
function filterKeys(obj: Record<string, unknown>, parentGroupKey = '', keys: string[]) {
|
||||||
const result = {}
|
const result: Record<string, unknown> = {}
|
||||||
|
|
||||||
for (const [namespaceKey, value] of Object.entries(obj)) {
|
for (const [namespaceKey, value] of Object.entries(obj)) {
|
||||||
// Skip $schema key
|
// Skip $schema key
|
||||||
@@ -13,7 +13,7 @@ function filterKeys(obj, parentGroupKey = '', keys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
const filteredObject = filterKeys(value, namespaceKey, keys)
|
const filteredObject = filterKeys(value as Record<string, unknown>, namespaceKey, keys)
|
||||||
if (Object.keys(filteredObject).length > 0) {
|
if (Object.keys(filteredObject).length > 0) {
|
||||||
result[namespaceKey] = filteredObject
|
result[namespaceKey] = filteredObject
|
||||||
}
|
}
|
||||||
@@ -40,13 +40,13 @@ function filterKeys(obj, parentGroupKey = '', keys) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortObject(obj) {
|
function sortObject(obj: Record<string, unknown>) {
|
||||||
const sortedObject = {}
|
const sortedObject: Record<string, unknown> = {}
|
||||||
Object.keys(obj)
|
Object.keys(obj)
|
||||||
.sort()
|
.sort()
|
||||||
.forEach((key) => {
|
.forEach((key) => {
|
||||||
if (typeof obj[key] === 'object') {
|
if (typeof obj[key] === 'object') {
|
||||||
sortedObject[key] = sortObject(obj[key])
|
sortedObject[key] = sortObject(obj[key] as Record<string, unknown>)
|
||||||
} else {
|
} else {
|
||||||
sortedObject[key] = obj[key]
|
sortedObject[key] = obj[key]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,9 +145,13 @@ export function t<
|
|||||||
|
|
||||||
const initTFunction: InitTFunction = (args) => {
|
const initTFunction: InitTFunction = (args) => {
|
||||||
const { config, language, translations } = args
|
const { config, language, translations } = args
|
||||||
const mergedTranslations = config?.translations?.[language]
|
const mergedTranslations =
|
||||||
? deepMergeSimple<DefaultTranslationsObject>(translations, config?.translations?.[language])
|
language && config?.translations?.[language as keyof typeof config.translations]
|
||||||
: translations
|
? deepMergeSimple<DefaultTranslationsObject>(
|
||||||
|
translations,
|
||||||
|
config.translations[language as keyof typeof config.translations]!,
|
||||||
|
)
|
||||||
|
: translations
|
||||||
|
|
||||||
return {
|
return {
|
||||||
t: (key, vars) => {
|
t: (key, vars) => {
|
||||||
@@ -161,18 +165,14 @@ const initTFunction: InitTFunction = (args) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function memoize(
|
function memoize<T extends Parameters<InitI18n>[0], K extends keyof T>(
|
||||||
fn: (args: Parameters<InitI18n>[0]) => Promise<I18n>,
|
fn: (args: T) => Promise<I18n>,
|
||||||
keys: string[],
|
keys: K[],
|
||||||
): (
|
): (args: T) => Promise<I18n> {
|
||||||
args: {
|
const cacheMap = new Map<string, I18n>()
|
||||||
context: 'api' | 'client'
|
|
||||||
} & Parameters<InitI18n>[0],
|
|
||||||
) => Promise<I18n> {
|
|
||||||
const cacheMap = new Map()
|
|
||||||
|
|
||||||
const memoized = async (args) => {
|
const memoized = async (args: T) => {
|
||||||
const cacheKey = keys.reduce((acc, key) => acc + args[key], '')
|
const cacheKey = keys.reduce((acc, key) => acc + String(args[key]), '')
|
||||||
|
|
||||||
if (!cacheMap.has(cacheKey)) {
|
if (!cacheMap.has(cacheKey)) {
|
||||||
const result = await fn(args)
|
const result = await fn(args)
|
||||||
@@ -187,7 +187,11 @@ function memoize(
|
|||||||
|
|
||||||
export const initI18n = memoize(
|
export const initI18n = memoize(
|
||||||
async ({ config, context, language = config.fallbackLanguage }) => {
|
async ({ config, context, language = config.fallbackLanguage }) => {
|
||||||
const translations = getTranslationsByContext(config.supportedLanguages[language], context)
|
if (!language || !config.supportedLanguages?.[language]) {
|
||||||
|
throw new Error(`Language ${language} not supported`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const translations = getTranslationsByContext(config.supportedLanguages?.[language], context)
|
||||||
|
|
||||||
const { t, translations: mergedTranslations } = initTFunction({
|
const { t, translations: mergedTranslations } = initTFunction({
|
||||||
config: config as any,
|
config: config as any,
|
||||||
@@ -202,7 +206,7 @@ export const initI18n = memoize(
|
|||||||
const i18n: I18n = {
|
const i18n: I18n = {
|
||||||
dateFNS,
|
dateFNS,
|
||||||
dateFNSKey,
|
dateFNSKey,
|
||||||
fallbackLanguage: config.fallbackLanguage,
|
fallbackLanguage: config.fallbackLanguage!,
|
||||||
language: language || config.fallbackLanguage,
|
language: language || config.fallbackLanguage,
|
||||||
t,
|
t,
|
||||||
translations: mergedTranslations,
|
translations: mergedTranslations,
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ function parseAcceptLanguage(acceptLanguageHeader: string): LanguagePreference[]
|
|||||||
export function extractHeaderLanguage(acceptLanguageHeader: string): AcceptedLanguages | undefined {
|
export function extractHeaderLanguage(acceptLanguageHeader: string): AcceptedLanguages | undefined {
|
||||||
const parsedHeader = parseAcceptLanguage(acceptLanguageHeader)
|
const parsedHeader = parseAcceptLanguage(acceptLanguageHeader)
|
||||||
|
|
||||||
let matchedLanguage: AcceptedLanguages
|
let matchedLanguage: AcceptedLanguages | undefined
|
||||||
|
|
||||||
for (const { language } of parsedHeader) {
|
for (const { language } of parsedHeader) {
|
||||||
if (!matchedLanguage && acceptedLanguages.includes(language)) {
|
if (!matchedLanguage && acceptedLanguages.includes(language)) {
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
"compilerOptions": {
|
|
||||||
/* TODO: remove the following lines */
|
|
||||||
"strict": false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user