From c7e86bc18b9986aed273d4c59b2c69fb3acfe520 Mon Sep 17 00:00:00 2001 From: Maor Shlomo Date: Thu, 19 Jan 2023 09:40:40 +0200 Subject: [PATCH 1/2] make i18n class generic --- typings/I18n.d.ts | 28 ++++++++++++++-------------- typings/typing.d.ts | 33 ++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/typings/I18n.d.ts b/typings/I18n.d.ts index ce90eb2..63159f8 100644 --- a/typings/I18n.d.ts +++ b/typings/I18n.d.ts @@ -3,36 +3,36 @@ import { Locales } from "./Locales"; import { Pluralization } from "./Pluralization"; import { MissingTranslation } from "./MissingTranslation"; import { interpolate } from "./helpers"; -export declare class I18n { +export declare class I18n { private _locale; private _defaultLocale; private _version; - onChangeHandlers: OnChangeHandler[]; + onChangeHandlers: OnChangeHandler[]; defaultSeparator: string; enableFallback: boolean; locales: Locales; pluralization: Pluralization; missingBehavior: string; - missingPlaceholder: MissingPlaceholderHandler; + missingPlaceholder: MissingPlaceholderHandler; missingTranslationPrefix: string; - nullPlaceholder: NullPlaceholderHandler; + nullPlaceholder: NullPlaceholderHandler; missingTranslation: MissingTranslation; placeholder: RegExp; - translations: Dict; + translations: Dict; transformKey: (key: string) => string; interpolate: typeof interpolate; - constructor(translations?: Dict, options?: Partial); - store(translations: Dict): void; + constructor(translations?: Dict, options?: Partial>); + store(translations: Dict): void; get locale(): string; set locale(newLocale: string); get defaultLocale(): string; set defaultLocale(newLocale: string); - translate(scope: Scope, options?: TranslateOptions): string | T; - t: (scope: Scope, options?: TranslateOptions) => string | T; - pluralize(count: number, scope: Scope, options?: TranslateOptions): string; - p: (count: number, scope: Scope, options?: TranslateOptions) => string; - localize(type: string, value: string | number | Date | null | undefined, options?: Dict): string; - l: (type: string, value: string | number | Date | null | undefined, options?: Dict) => string; + translate(scope: Scope, options?: TranslateOptions): string | T; + t: (scope: Scope, options?: TranslateOptions) => string | T; + pluralize(count: number, scope: Scope, options?: TranslateOptions): string; + p: (count: number, scope: Scope, options?: TranslateOptions) => string; + localize(type: string, value: string | number | Date | null | undefined, options?: Dict): string; + l: (type: string, value: string | number | Date | null | undefined, options?: Dict) => string; toTime(scope: Scope, input: DateTime): string; numberToCurrency(input: Numeric, options?: Partial): string; numberToPercentage(input: Numeric, options?: Partial): string; @@ -48,7 +48,7 @@ export declare class I18n { toSentence(items: any[], options?: Partial): string; timeAgoInWords(fromTime: DateTime, toTime: DateTime, options?: TimeAgoInWordsOptions): string; distanceOfTimeInWords: (fromTime: DateTime, toTime: DateTime, options?: TimeAgoInWordsOptions) => string; - onChange(callback: OnChangeHandler): () => void; + onChange(callback: OnChangeHandler): () => void; get version(): number; formatNumber(input: Numeric, options: FormatNumberOptions): string; get(scope: Scope): any; diff --git a/typings/typing.d.ts b/typings/typing.d.ts index b5ed8ef..3123876 100644 --- a/typings/typing.d.ts +++ b/typings/typing.d.ts @@ -1,7 +1,7 @@ import BigNumber from "bignumber.js"; import { I18n } from "./I18n"; -export interface Dict { - [key: string]: any; +export interface Dict { + [key: string]: T; } export type DateTime = string | number | Date; export interface TimeAgoInWordsOptions { @@ -51,32 +51,32 @@ export interface ObjectType { [key: string]: PrimitiveType | ArrayType | ObjectType; } type MissingBehavior = "message" | "guess" | "error"; -export interface I18nOptions { +export interface I18nOptions { defaultLocale: string; defaultSeparator: string; enableFallback: boolean; locale: string; missingBehavior: MissingBehavior; - missingPlaceholder: MissingPlaceholderHandler; - nullPlaceholder: NullPlaceholderHandler; + missingPlaceholder: MissingPlaceholderHandler; + nullPlaceholder: NullPlaceholderHandler; missingTranslationPrefix: string; placeholder: RegExp; transformKey: (key: string) => string; } export type Scope = string | string[]; -export type LocaleResolver = (i18n: I18n, locale: string) => string[]; -export type Pluralizer = (i18n: I18n, count: number) => string[]; -export type MissingTranslationStrategy = (i18n: I18n, scope: Scope, options: Dict) => string; -export interface TranslateOptions { +export type LocaleResolver = (i18n: I18n, locale: string) => string[]; +export type Pluralizer = (i18n: I18n, count: number) => string[]; +export type MissingTranslationStrategy = (i18n: I18n, scope: Scope, options: Dict) => string; +export interface TranslateOptions { defaultValue?: any; count?: number; scope?: Scope; - defaults?: Dict[]; + defaults?: Dict[]; missingBehavior?: MissingBehavior | string; [key: string]: any; } -export type MissingPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; -export type NullPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; +export type MissingPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; +export type NullPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; export type DayNames = [string, string, string, string, string, string, string]; export type MonthNames = [ null, @@ -103,5 +103,12 @@ export interface StrftimeOptions { monthNames: MonthNames; abbrMonthNames: MonthNames; } -export type OnChangeHandler = (i18n: I18n) => void; +export type OnChangeHandler = (i18n: I18n) => void; + +export type NestedKeyOf = + {[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object + ? `${Key}` | `${Key}.${NestedKeyOf}` + : `${Key}` + }[keyof ObjectType & (string | number)]; + export {}; From 25f30cbd6f138e7b87d6a55931270bd0aa3174c1 Mon Sep 17 00:00:00 2001 From: Maor Shlomo Date: Thu, 19 Jan 2023 09:49:26 +0200 Subject: [PATCH 2/2] Add to changelog and add extends object to --- CHANGELOG.md | 1 + typings/I18n.d.ts | 30 +++++++++++++++--------------- typings/typing.d.ts | 16 ++++++++-------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bca9c21..dc96bf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ project adheres to [Semantic Versioning](http://semver.org/). pluralizers on top of [make-plural](https://github.com/eemeli/make-plural/). - [Changed] Use `make-plural`'s `en` function as the default pluralizer. - [Changed] Mark `Scope` type as read-only. +- [Changed] Add Generic type Instead of `Scope`. ## V4.2.2 - Dec 16, 2022 diff --git a/typings/I18n.d.ts b/typings/I18n.d.ts index 63159f8..f78961d 100644 --- a/typings/I18n.d.ts +++ b/typings/I18n.d.ts @@ -1,38 +1,38 @@ -import { DateTime, Dict, FormatNumberOptions, I18nOptions, MissingPlaceholderHandler, NullPlaceholderHandler, NumberToCurrencyOptions, NumberToDelimitedOptions, NumberToHumanOptions, NumberToHumanSizeOptions, NumberToPercentageOptions, NumberToRoundedOptions, Numeric, OnChangeHandler, Scope, StrftimeOptions, TimeAgoInWordsOptions, ToSentenceOptions, TranslateOptions } from "./typing"; +import { DateTime, Dict, FormatNumberOptions, I18nOptions, MissingPlaceholderHandler, NestedKeyOf, NullPlaceholderHandler, NumberToCurrencyOptions, NumberToDelimitedOptions, NumberToHumanOptions, NumberToHumanSizeOptions, NumberToPercentageOptions, NumberToRoundedOptions, Numeric, OnChangeHandler, Scope, StrftimeOptions, TimeAgoInWordsOptions, ToSentenceOptions, TranslateOptions } from "./typing"; import { Locales } from "./Locales"; import { Pluralization } from "./Pluralization"; import { MissingTranslation } from "./MissingTranslation"; import { interpolate } from "./helpers"; -export declare class I18n { +export declare class I18n { private _locale; private _defaultLocale; private _version; - onChangeHandlers: OnChangeHandler[]; + onChangeHandlers: OnChangeHandler[]; defaultSeparator: string; enableFallback: boolean; locales: Locales; pluralization: Pluralization; missingBehavior: string; - missingPlaceholder: MissingPlaceholderHandler; + missingPlaceholder: MissingPlaceholderHandler; missingTranslationPrefix: string; - nullPlaceholder: NullPlaceholderHandler; + nullPlaceholder: NullPlaceholderHandler; missingTranslation: MissingTranslation; placeholder: RegExp; - translations: Dict; + translations: Dict; transformKey: (key: string) => string; interpolate: typeof interpolate; - constructor(translations?: Dict, options?: Partial>); - store(translations: Dict): void; + constructor(translations?: Dict, options?: Partial>); + store(translations: Dict): void; get locale(): string; set locale(newLocale: string); get defaultLocale(): string; set defaultLocale(newLocale: string); - translate(scope: Scope, options?: TranslateOptions): string | T; - t: (scope: Scope, options?: TranslateOptions) => string | T; - pluralize(count: number, scope: Scope, options?: TranslateOptions): string; - p: (count: number, scope: Scope, options?: TranslateOptions) => string; - localize(type: string, value: string | number | Date | null | undefined, options?: Dict): string; - l: (type: string, value: string | number | Date | null | undefined, options?: Dict) => string; + translate(scope: Scope, options?: TranslateOptions): string | T; + t: (scope: NestedKeyOf, options?: TranslateOptions) => string | T; + pluralize(count: number, scope: Scope, options?: TranslateOptions): string; + p: (count: number, scope: Scope, options?: TranslateOptions) => string; + localize(type: string, value: string | number | Date | null | undefined, options?: Dict): string; + l: (type: string, value: string | number | Date | null | undefined, options?: Dict) => string; toTime(scope: Scope, input: DateTime): string; numberToCurrency(input: Numeric, options?: Partial): string; numberToPercentage(input: Numeric, options?: Partial): string; @@ -48,7 +48,7 @@ export declare class I18n { toSentence(items: any[], options?: Partial): string; timeAgoInWords(fromTime: DateTime, toTime: DateTime, options?: TimeAgoInWordsOptions): string; distanceOfTimeInWords: (fromTime: DateTime, toTime: DateTime, options?: TimeAgoInWordsOptions) => string; - onChange(callback: OnChangeHandler): () => void; + onChange(callback: OnChangeHandler): () => void; get version(): number; formatNumber(input: Numeric, options: FormatNumberOptions): string; get(scope: Scope): any; diff --git a/typings/typing.d.ts b/typings/typing.d.ts index 3123876..5cd105e 100644 --- a/typings/typing.d.ts +++ b/typings/typing.d.ts @@ -51,7 +51,7 @@ export interface ObjectType { [key: string]: PrimitiveType | ArrayType | ObjectType; } type MissingBehavior = "message" | "guess" | "error"; -export interface I18nOptions { +export interface I18nOptions { defaultLocale: string; defaultSeparator: string; enableFallback: boolean; @@ -64,10 +64,10 @@ export interface I18nOptions { transformKey: (key: string) => string; } export type Scope = string | string[]; -export type LocaleResolver = (i18n: I18n, locale: string) => string[]; -export type Pluralizer = (i18n: I18n, count: number) => string[]; -export type MissingTranslationStrategy = (i18n: I18n, scope: Scope, options: Dict) => string; -export interface TranslateOptions { +export type LocaleResolver = (i18n: I18n, locale: string) => string[]; +export type Pluralizer = (i18n: I18n, count: number) => string[]; +export type MissingTranslationStrategy = (i18n: I18n, scope: Scope, options: Dict) => string; +export interface TranslateOptions { defaultValue?: any; count?: number; scope?: Scope; @@ -75,8 +75,8 @@ export interface TranslateOptions { missingBehavior?: MissingBehavior | string; [key: string]: any; } -export type MissingPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; -export type NullPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; +export type MissingPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; +export type NullPlaceholderHandler = (i18n: I18n, placeholder: string, message: string, options: Dict) => string; export type DayNames = [string, string, string, string, string, string, string]; export type MonthNames = [ null, @@ -103,7 +103,7 @@ export interface StrftimeOptions { monthNames: MonthNames; abbrMonthNames: MonthNames; } -export type OnChangeHandler = (i18n: I18n) => void; +export type OnChangeHandler = (i18n: I18n) => void; export type NestedKeyOf = {[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object