diff --git a/hassio/src/supervisor-base-element.ts b/hassio/src/supervisor-base-element.ts index a5d3fbb7f6..7d9ee78d07 100644 --- a/hassio/src/supervisor-base-element.ts +++ b/hassio/src/supervisor-base-element.ts @@ -25,7 +25,7 @@ import { } from "../../src/data/supervisor/supervisor"; import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin"; import { urlSyncMixin } from "../../src/state/url-sync-mixin"; -import { HomeAssistant, Route } from "../../src/types"; +import { HomeAssistant, Route, TranslationDict } from "../../src/types"; import { getTranslation } from "../../src/util/common-translation"; declare global { @@ -124,9 +124,13 @@ export class SupervisorBaseElement extends urlSyncMixin( this.supervisor = { ...this.supervisor, - localize: await computeLocalize(this.constructor.prototype, language, { - [language]: data, - }), + localize: await computeLocalize( + this.constructor.prototype, + language, + { + [language]: data, + } + ), }; } diff --git a/src/common/translations/localize.ts b/src/common/translations/localize.ts index f82d6f0e38..13c3b8c920 100644 --- a/src/common/translations/localize.ts +++ b/src/common/translations/localize.ts @@ -3,10 +3,41 @@ import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-plur import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/lib/should-polyfill"; import { shouldPolyfill as shouldPolyfillDateTime } from "@formatjs/intl-datetimeformat/lib/should-polyfill"; import IntlMessageFormat from "intl-messageformat"; -import { Resources } from "../../types"; +import { Resources, TranslationDict } from "../../types"; import { getLocalLanguage } from "../../util/common-translation"; -export type LocalizeFunc = (key: string, ...args: any[]) => string; +// Exclude some patterns from key type checking for now +// These are intended to be removed as errors are fixed +// Fixing component category will require tighter definition of types from backend and/or web socket +type LocalizeKeyExceptions = + | `${string}` + | `panel.${string}` + | `state.${string}` + | `state_attributes.${string}` + | `state_badge.${string}` + | `groups.${string}` + | `config_entry.${string}` + | `ui.${string}` + | `${keyof TranslationDict["supervisor"]}.${string}` + | `component.${string}`; + +// Tweaked from https://www.raygesualdo.com/posts/flattening-object-keys-with-typescript-types +type FlattenObjectKeys< + T extends Record, + Key extends keyof T = keyof T +> = Key extends string + ? T[Key] extends Record + ? `${Key}.${FlattenObjectKeys}` + : `${Key}` + : never; + +export type LocalizeFunc< + Dict extends Record = TranslationDict +> = ( + key: FlattenObjectKeys | LocalizeKeyExceptions, + ...args: any[] +) => string; + interface FormatType { [format: string]: any; } @@ -65,12 +96,14 @@ export const polyfillsLoaded = * } */ -export const computeLocalize = async ( +export const computeLocalize = async < + Dict extends Record = TranslationDict +>( cache: any, language: string, resources: Resources, formats?: FormatsType -): Promise => { +): Promise> => { if (polyfillsLoaded) { await polyfillsLoaded; } diff --git a/src/data/supervisor/supervisor.ts b/src/data/supervisor/supervisor.ts index 965d51506b..62812b2c59 100644 --- a/src/data/supervisor/supervisor.ts +++ b/src/data/supervisor/supervisor.ts @@ -1,7 +1,7 @@ import { Connection, getCollection } from "home-assistant-js-websocket"; import { Store } from "home-assistant-js-websocket/dist/store"; import { LocalizeFunc } from "../../common/translations/localize"; -import { HomeAssistant } from "../../types"; +import { HomeAssistant, TranslationDict } from "../../types"; import { HassioAddonsInfo } from "../hassio/addon"; import { HassioHassOSInfo, HassioHostInfo } from "../hassio/host"; import { NetworkInfo } from "../hassio/network"; @@ -67,7 +67,7 @@ export interface Supervisor { os: HassioHassOSInfo; addon: HassioAddonsInfo; store: SupervisorStore; - localize: LocalizeFunc; + localize: LocalizeFunc; } export const supervisorApiWsRequest = ( diff --git a/src/types.ts b/src/types.ts index b6bab9a982..62f6e89366 100644 --- a/src/types.ts +++ b/src/types.ts @@ -151,6 +151,8 @@ export interface TranslationMetadata { }; } +export type TranslationDict = typeof import("./translations/en.json"); + export interface IconMetaFile { version: string; parts: IconMeta[];