diff --git a/.eslintrc.yml b/.eslintrc.yml index 7103cf8e..834317c1 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -91,6 +91,8 @@ overrides: no-param-reassign: off - files: - '**/*.ts' + excludedFiles: + - './index-lt-4.7.4.d.ts' plugins: - '@typescript-eslint' parserOptions: @@ -114,3 +116,10 @@ overrides: '@typescript-eslint/no-unnecessary-type-assertion': error '@typescript-eslint/func-call-spacing': error prefer-const: off + - files: + - './index-lt-4.7.4.d.ts' + parserOptions: + project: null + rules: + no-unused-vars: off + no-undef: off diff --git a/copy-types.mjs b/copy-types.mjs index 0c8742ca..26b6d1ae 100644 --- a/copy-types.mjs +++ b/copy-types.mjs @@ -1,3 +1,4 @@ import { cp } from 'node:fs/promises'; await cp('index.d.ts', 'index.d.cts'); +await cp('index-lt-4.7.4.d.ts', 'index-lt-4.7.4.d.cts'); diff --git a/index-lt-4.7.4.d.ts b/index-lt-4.7.4.d.ts new file mode 100644 index 00000000..29f2f94e --- /dev/null +++ b/index-lt-4.7.4.d.ts @@ -0,0 +1,20 @@ +export * from './index'; + +declare global { + // `Intl.LocalesArgument` type was recently added to TS — polyfilled here via `typesVersions` in `package.json` for + // compatibility with TS versions older than v4.7.4. + // TODO: Revisit/remove once TS >= v4.7.4 is widespread enough. + namespace Intl { + /** + * The locale or locales to use + * + * See [MDN - Intl - locales + * argument](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument) + */ + type LocalesArgument = + | UnicodeBCP47LocaleIdentifier + | globalThis.Intl.Locale + | readonly (UnicodeBCP47LocaleIdentifier | globalThis.Intl.Locale)[] + | undefined; + } +} diff --git a/index.d.ts b/index.d.ts index 585c81f2..2527966f 100644 --- a/index.d.ts +++ b/index.d.ts @@ -548,7 +548,7 @@ export namespace Temporal { subtract(other: Temporal.Duration | DurationLike | string, options?: DurationArithmeticOptions): Temporal.Duration; round(roundTo: DurationRoundTo): Temporal.Duration; total(totalOf: DurationTotalOf): number; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: ToStringPrecisionOptions): string; valueOf(): never; @@ -601,7 +601,7 @@ export namespace Temporal { ): Temporal.Instant; toZonedDateTime(calendarAndTimeZone: { timeZone: TimeZoneLike; calendar: CalendarLike }): Temporal.ZonedDateTime; toZonedDateTimeISO(tzLike: TimeZoneLike): Temporal.ZonedDateTime; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: InstantToStringOptions): string; valueOf(): never; @@ -836,7 +836,7 @@ export namespace Temporal { toPlainYearMonth(): Temporal.PlainYearMonth; toPlainMonthDay(): Temporal.PlainMonthDay; getISOFields(): PlainDateISOFields; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: ShowCalendarOption): string; valueOf(): never; @@ -955,7 +955,7 @@ export namespace Temporal { toPlainMonthDay(): Temporal.PlainMonthDay; toPlainTime(): Temporal.PlainTime; getISOFields(): PlainDateTimeISOFields; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: CalendarTypeToStringOptions): string; valueOf(): never; @@ -992,7 +992,7 @@ export namespace Temporal { with(monthDayLike: PlainMonthDayLike, options?: AssignmentOptions): Temporal.PlainMonthDay; toPlainDate(year: { year: number }): Temporal.PlainDate; getISOFields(): PlainDateISOFields; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: ShowCalendarOption): string; valueOf(): never; @@ -1085,7 +1085,7 @@ export namespace Temporal { plainDate: Temporal.PlainDate | PlainDateLike | string; }): Temporal.ZonedDateTime; getISOFields(): PlainTimeISOFields; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: ToStringPrecisionOptions): string; valueOf(): never; @@ -1199,7 +1199,7 @@ export namespace Temporal { ): Temporal.Duration; toPlainDate(day: { day: number }): Temporal.PlainDate; getISOFields(): PlainDateISOFields; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: ShowCalendarOption): string; valueOf(): never; @@ -1312,7 +1312,7 @@ export namespace Temporal { toPlainMonthDay(): Temporal.PlainMonthDay; toPlainTime(): Temporal.PlainTime; getISOFields(): ZonedDateTimeISOFields; - toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; + toLocaleString(locales?: globalThis.Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string; toJSON(): string; toString(options?: ZonedDateTimeToStringOptions): string; valueOf(): never; @@ -1537,15 +1537,15 @@ declare namespace Intl { * Creates `Intl.DateTimeFormat` objects that enable language-sensitive * date and time formatting. */ - new (locales?: string | string[], options?: DateTimeFormatOptions): DateTimeFormat; - (locales?: string | string[], options?: DateTimeFormatOptions): DateTimeFormat; + new (locales?: globalThis.Intl.LocalesArgument, options?: DateTimeFormatOptions): DateTimeFormat; + (locales?: globalThis.Intl.LocalesArgument, options?: DateTimeFormatOptions): DateTimeFormat; /** * Get an array containing those of the provided locales that are supported * in date and time formatting without having to fall back to the runtime's * default locale. */ - supportedLocalesOf(locales: string | string[], options?: DateTimeFormatOptions): string[]; + supportedLocalesOf(locales: globalThis.Intl.LocalesArgument, options?: DateTimeFormatOptions): string[]; }; } diff --git a/lib/intl.ts b/lib/intl.ts index 84ae40b5..8d0d9579 100644 --- a/lib/intl.ts +++ b/lib/intl.ts @@ -117,8 +117,12 @@ function DateTimeFormatImpl( } const hasOptions = typeof optionsParam !== 'undefined'; const options = hasOptions ? ObjectAssign({}, optionsParam) : {}; - // TODO: remove type assertion after Temporal types land in TS lib types - const original = new IntlDateTimeFormat(locale, options as globalThis.Intl.DateTimeFormatOptions); + const original = new IntlDateTimeFormat( + // TODO: remove type assertion after TS lib types updated per https://github.com/microsoft/TypeScript/issues/52946 + locale as ConstructorParameters[0], + // TODO: remove type assertion after Temporal types land in TS lib types + options as globalThis.Intl.DateTimeFormatOptions + ); const ro = original.resolvedOptions(); // DateTimeFormat instances are very expensive to create. Therefore, they will @@ -169,7 +173,12 @@ DateTimeFormatImpl.supportedLocalesOf = function ( locales: Params['supportedLocalesOf'][0], options: Params['supportedLocalesOf'][1] ) { - return IntlDateTimeFormat.supportedLocalesOf(locales, options as globalThis.Intl.DateTimeFormatOptions); + return IntlDateTimeFormat.supportedLocalesOf( + // TODO: remove type assertion after TS lib types updated per https://github.com/microsoft/TypeScript/issues/52946 + locales as Parameters[0], + // TODO: remove type assertion after Temporal types land in TS lib types + options as globalThis.Intl.DateTimeFormatOptions + ); }; const propertyDescriptors: Partial> = { diff --git a/package.json b/package.json index fb8f6284..006f1b35 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,12 @@ { "import": { "types": "./index.d.ts", + "types@<4.7.4": "./index-lt-4.7.4.d.ts", "default": "./dist/index.esm.js" }, "require": { "types": "./index.d.cts", + "types@<4.7.4": "./index-lt-4.7.4.d.cts", "default": "./dist/index.cjs" }, "default": "./dist/index.cjs" @@ -23,6 +25,13 @@ ] }, "types": "./index.d.ts", + "typesVersions": { + "<4.7.4": { + "index.d.ts": [ + "index-lt-4.7.4.d.ts" + ] + } + }, "scripts": { "test": "npm run build && node --no-warnings --experimental-modules --experimental-specifier-resolution=node --icu-data-dir node_modules/full-icu --loader ./test/resolve.source.mjs ./test/all.mjs", "test262": "TEST262=1 npm run build && node runtest262.mjs \"$@\"",