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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-console */
|
||||
import fs from 'fs'
|
||||
|
||||
export function copyFile(source, destination) {
|
||||
export function copyFile(source: string, destination: string) {
|
||||
fs.copyFile(source, destination, (err) => {
|
||||
if (err) {
|
||||
// Handle error
|
||||
|
||||
@@ -13,9 +13,12 @@ export function deepMergeSimple<T = object>(obj1: object, obj2: object): T {
|
||||
|
||||
for (const key in obj2) {
|
||||
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]) {
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
output[key] = deepMergeSimple(obj1[key], obj2[key])
|
||||
} else {
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
output[key] = obj2[key]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import fs from 'fs'
|
||||
|
||||
export function ensureDirectoryExists(directory) {
|
||||
export function ensureDirectoryExists(directory: string) {
|
||||
try {
|
||||
if (!fs.existsSync(directory)) {
|
||||
fs.mkdirSync(directory, { recursive: true })
|
||||
}
|
||||
} 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 => {
|
||||
// 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')) {
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
if (label[i18n.language]) {
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
return label[i18n.language]
|
||||
}
|
||||
|
||||
@@ -25,8 +27,9 @@ export const getTranslation = <T extends LabelType>(
|
||||
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]]
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { Language } from '../types.js'
|
||||
|
||||
import { clientTranslationKeys } from '../clientKeys.js'
|
||||
|
||||
function filterKeys(obj, parentGroupKey = '', keys) {
|
||||
const result = {}
|
||||
function filterKeys(obj: Record<string, unknown>, parentGroupKey = '', keys: string[]) {
|
||||
const result: Record<string, unknown> = {}
|
||||
|
||||
for (const [namespaceKey, value] of Object.entries(obj)) {
|
||||
// Skip $schema key
|
||||
@@ -13,7 +13,7 @@ function filterKeys(obj, parentGroupKey = '', keys) {
|
||||
}
|
||||
|
||||
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) {
|
||||
result[namespaceKey] = filteredObject
|
||||
}
|
||||
@@ -40,13 +40,13 @@ function filterKeys(obj, parentGroupKey = '', keys) {
|
||||
return result
|
||||
}
|
||||
|
||||
function sortObject(obj) {
|
||||
const sortedObject = {}
|
||||
function sortObject(obj: Record<string, unknown>) {
|
||||
const sortedObject: Record<string, unknown> = {}
|
||||
Object.keys(obj)
|
||||
.sort()
|
||||
.forEach((key) => {
|
||||
if (typeof obj[key] === 'object') {
|
||||
sortedObject[key] = sortObject(obj[key])
|
||||
sortedObject[key] = sortObject(obj[key] as Record<string, unknown>)
|
||||
} else {
|
||||
sortedObject[key] = obj[key]
|
||||
}
|
||||
|
||||
@@ -145,9 +145,13 @@ export function t<
|
||||
|
||||
const initTFunction: InitTFunction = (args) => {
|
||||
const { config, language, translations } = args
|
||||
const mergedTranslations = config?.translations?.[language]
|
||||
? deepMergeSimple<DefaultTranslationsObject>(translations, config?.translations?.[language])
|
||||
: translations
|
||||
const mergedTranslations =
|
||||
language && config?.translations?.[language as keyof typeof config.translations]
|
||||
? deepMergeSimple<DefaultTranslationsObject>(
|
||||
translations,
|
||||
config.translations[language as keyof typeof config.translations]!,
|
||||
)
|
||||
: translations
|
||||
|
||||
return {
|
||||
t: (key, vars) => {
|
||||
@@ -161,18 +165,14 @@ const initTFunction: InitTFunction = (args) => {
|
||||
}
|
||||
}
|
||||
|
||||
function memoize(
|
||||
fn: (args: Parameters<InitI18n>[0]) => Promise<I18n>,
|
||||
keys: string[],
|
||||
): (
|
||||
args: {
|
||||
context: 'api' | 'client'
|
||||
} & Parameters<InitI18n>[0],
|
||||
) => Promise<I18n> {
|
||||
const cacheMap = new Map()
|
||||
function memoize<T extends Parameters<InitI18n>[0], K extends keyof T>(
|
||||
fn: (args: T) => Promise<I18n>,
|
||||
keys: K[],
|
||||
): (args: T) => Promise<I18n> {
|
||||
const cacheMap = new Map<string, I18n>()
|
||||
|
||||
const memoized = async (args) => {
|
||||
const cacheKey = keys.reduce((acc, key) => acc + args[key], '')
|
||||
const memoized = async (args: T) => {
|
||||
const cacheKey = keys.reduce((acc, key) => acc + String(args[key]), '')
|
||||
|
||||
if (!cacheMap.has(cacheKey)) {
|
||||
const result = await fn(args)
|
||||
@@ -187,7 +187,11 @@ function memoize(
|
||||
|
||||
export const initI18n = memoize(
|
||||
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({
|
||||
config: config as any,
|
||||
@@ -202,7 +206,7 @@ export const initI18n = memoize(
|
||||
const i18n: I18n = {
|
||||
dateFNS,
|
||||
dateFNSKey,
|
||||
fallbackLanguage: config.fallbackLanguage,
|
||||
fallbackLanguage: config.fallbackLanguage!,
|
||||
language: language || config.fallbackLanguage,
|
||||
t,
|
||||
translations: mergedTranslations,
|
||||
|
||||
@@ -152,7 +152,7 @@ function parseAcceptLanguage(acceptLanguageHeader: string): LanguagePreference[]
|
||||
export function extractHeaderLanguage(acceptLanguageHeader: string): AcceptedLanguages | undefined {
|
||||
const parsedHeader = parseAcceptLanguage(acceptLanguageHeader)
|
||||
|
||||
let matchedLanguage: AcceptedLanguages
|
||||
let matchedLanguage: AcceptedLanguages | undefined
|
||||
|
||||
for (const { language } of parsedHeader) {
|
||||
if (!matchedLanguage && acceptedLanguages.includes(language)) {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
/* TODO: remove the following lines */
|
||||
"strict": false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user