lang-tag
Version:
A professional solution for managing translations in modern JavaScript/TypeScript projects, especially those using component-based architectures. `lang-tag` simplifies internationalization by allowing you to define translation keys directly within the com
186 lines (185 loc) • 10.5 kB
TypeScript
/**
* Configuration for LangTag translations.
* @template Namespaces - The type used for namespaces, defaults to string.
*/
export interface LangTagTranslationsConfig<Namespaces = string> {
/** Optional base path for translation keys. */
path?: string;
/** The namespace for the translations. */
namespace: Namespaces;
}
/**
* Represents a collection of translations.
* Keys are strings, and values can be either strings (translations)
* or nested LangTagTranslations objects for hierarchical translations.
*/
export type LangTagTranslations = {
[key: string]: string | LangTagTranslations;
};
/**
* Defines the structure for parameters used in interpolation.
* It's a record where keys are placeholders and values are their replacements.
*/
export type InterpolationParams = Record<string, any>;
/**
* Represents a function that takes optional interpolation parameters
* and returns a translated string.
*/
export type ParameterizedTranslation = (params?: InterpolationParams) => string;
/**
* Transforms a static translation object into an object where each
* translation string or nested object is converted into a callable function
* or a nested structure of callable functions.
* @template T - The structure of the input translations.
*/
export type CallableTranslations<T> = {
[P in keyof T]: T[P] extends ParameterizedTranslation ? ParameterizedTranslation : T[P] extends (...args: any[]) => string ? T[P] : T[P] extends Record<string, any> ? CallableTranslations<T[P]> : ParameterizedTranslation;
};
/**
* Context provided to a translation transformer function.
* @template Config - The LangTag translations configuration type.
*/
export interface TranslationTransformContext<Config extends LangTagTranslationsConfig> {
/** The LangTag configuration object. */
config: Config | undefined;
/** The path of the direct parent object of the current translation key, including the base path from config. */
parentPath: string;
/** The full path to the current translation key, including the base path from config. */
path: string;
/** The path to the current translation key, relative to the root of the translations object (excluding the base path from config). */
unprefixedPath: string;
/** The current translation key. */
key: string;
/** The raw string value of the translation. */
value: string;
/** Optional interpolation parameters for the translation. */
params?: InterpolationParams;
}
/**
* Defines the signature for a function that transforms a raw translation string.
* @template Config - The LangTag translations configuration type.
* @param transformContext - The context for the transformation.
* @returns The transformed translation string.
*/
type TranslationTransformer<Config extends LangTagTranslationsConfig> = (transformContext: TranslationTransformContext<Config>) => string;
/**
* Context provided to a translation key processor function.
* It omits the 'params' field from `TranslationTransformContext`.
* @template Config - The LangTag translations configuration type.
*/
export type TranslationKeyProcessorContext<Config extends LangTagTranslationsConfig> = Omit<TranslationTransformContext<Config>, 'params'>;
/**
* Defines the signature for a function that processes translation keys.
* This allows for modifying or generating new keys based on the original key and value.
* @template Config - The LangTag translations configuration type.
*/
export type TranslationKeyProcessor<Config extends LangTagTranslationsConfig = LangTagTranslationsConfig> = (
/** Context for processing the key. */
context: TranslationKeyProcessorContext<Config>,
/**
* Callback to add a processed key.
* @param newKey - The new key to be added to the result.
* @param originalValue - The original string value associated with the key being processed.
*/
addProcessedKey: (newKey: string, originalValue: string) => void) => void;
/**
* Defines the strategy for mapping and transforming translations.
* @template Config - The LangTag translations configuration type.
*/
export interface TranslationMappingStrategy<Config extends LangTagTranslationsConfig> {
/** The function used to transform raw translation strings. */
transform: TranslationTransformer<Config>;
/** Optional function to process translation keys. */
processKey?: TranslationKeyProcessor<Config>;
}
/**
* Creates a callable translations object from a static translations object.
* This function initializes the transformation process.
* @template T - The type of the input translations object.
* @template Config - The LangTag translations configuration type.
* @param translations - The static translations object.
* @param config - The LangTag configuration object.
* @param strategy - The translation mapping strategy.
* @returns A callable translations object.
*/
export declare function createCallableTranslations<T extends LangTagTranslations, Config extends LangTagTranslationsConfig>(translations: T, config: Config | undefined, strategy: TranslationMappingStrategy<Config>): CallableTranslations<T>;
/**
* Helper type to determine the flexible value of a translation property.
* If `T` is a function returning a string, it can be `T` or `string`.
* If `T` is a record, it recursively applies `RecursiveFlexibleTranslations`.
* Otherwise, it can be `ParameterizedTranslation`, `T`, or `string`.
* @template T - The type of the property value.
* @template IsPartial - A boolean indicating whether properties should be optional.
*/
type FlexibleValue<T, IsPartial extends boolean> = T extends (...args: any[]) => string ? T | string : T extends Record<string, any> ? RecursiveFlexibleTranslations<T, IsPartial> : ParameterizedTranslation | T | string;
/**
* Core type for flexible translations, allowing properties to be optional recursively.
* This type serves as the foundation for `FlexibleTranslations` and `PartialFlexibleTranslations`.
* It transforms a given translation structure `T` into a flexible version where each property
* can be its original type, a string, or a `ParameterizedTranslation` function.
* If `IsPartial` is true, all properties at all levels of nesting become optional.
*
* @template T The original, un-transformed, structure of the translations.
* @template IsPartial A boolean indicating whether properties should be optional.
* If true, all properties at all levels become optional (e.g., `string | undefined`).
* If false, properties are required (e.g., `string`).
*/
export type RecursiveFlexibleTranslations<T, IsPartial extends boolean> = IsPartial extends true ? {
[P in keyof T]?: FlexibleValue<T[P], IsPartial>;
} : {
[P in keyof T]: FlexibleValue<T[P], IsPartial>;
};
/**
* Represents a flexible structure for translations where all properties are required, based on an original type `T`.
* Allows for strings, `ParameterizedTranslation` functions, or other compatible functions
* at any level of the translation object. This provides flexibility in how translations
* are initially defined.
* This type is an alias for `RecursiveFlexibleTranslations<T, false>`.
* @template T - The original structure of the translations.
*/
export type FlexibleTranslations<T> = RecursiveFlexibleTranslations<T, false>;
/**
* Represents a deeply partial version of the structure that `FlexibleTranslations<T>` would produce, based on an original type `T`.
* All properties at all levels of nesting are made optional.
* The transformation rules for property types mirror those in `FlexibleTranslations<T>`.
* This type is an alias for `RecursiveFlexibleTranslations<T, true>`.
* @template T - The original, un-transformed, structure of the translations. This is the same kind of type argument that `FlexibleTranslations<T>` expects.
*/
export type PartialFlexibleTranslations<T> = RecursiveFlexibleTranslations<T, true>;
/**
* Normalizes a `FlexibleTranslations` or `PartialFlexibleTranslations` object into a `CallableTranslations` object.
* Converts plain strings into `ParameterizedTranslation` functions and ensures
* that all callable elements conform to the `ParameterizedTranslation` signature.
* Only properties present in the input `translations` object will be processed and included in the result.
* @template T - The structure of the original translations.
* @param translations - The flexible or partial flexible translations object to normalize.
* @returns A `CallableTranslations` object. The returned object will only contain callable translations for properties that were present in the input `translations` object.
*/
export declare function normalizeTranslations<T>(translations: RecursiveFlexibleTranslations<T, boolean>): CallableTranslations<T>;
/**
* Retrieves a translation function from a nested translation object using a dot-separated path.
* It is recommended to use an unprefixed path (a path that does not include the base path from the configuration)
* with this function, as it operates on the structure of the callable translations object where keys are unprefixed.
* @template T - The type of the translations object.
* @param translations The object containing translation functions.
* @param dottedPath A string path using dot notation (e.g., "user.profile.greeting"). This path should generally be unprefixed.
* @returns The translation function, or null if not found or invalid.
*/
export declare function lookupTranslation<T>(translations: CallableTranslations<T>, dottedPath: string): ParameterizedTranslation | null;
/**
* Processes placeholders in a translation string.
* If the input `translation` is not a string, it returns an empty string.
* Otherwise, it replaces placeholders in the format `{{placeholder}}` with values from `params`.
* If a placeholder is not found in `params`, it's replaced with an empty string.
* @param translation The translation value to process. Can be of any type.
* @param params Optional interpolation parameters.
* @returns The processed string, or an empty string if the input was not a string.
*/
export declare function processPlaceholders(translation: any, params?: InterpolationParams): string;
/**
* Default transformer for translations.
* Uses `processPlaceholders` to replace placeholders in the format `{{placeholder}}`
* with values from `params`.
*/
export declare const defaultTranslationTransformer: TranslationTransformer<LangTagTranslationsConfig>;
export {};