Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript: allow Intl.Locale objects in locale list params #224

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions .eslintrc.yml
Expand Up @@ -91,6 +91,8 @@ overrides:
no-param-reassign: off
- files:
- '**/*.ts'
excludedFiles:
- './index-lt-4.7.4.d.ts'
plugins:
- '@typescript-eslint'
parserOptions:
Expand All @@ -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
1 change: 1 addition & 0 deletions 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');
20 changes: 20 additions & 0 deletions index-lt-4.7.4.d.ts
@@ -0,0 +1,20 @@
export * from './index';

declare global {
lionel-rowe marked this conversation as resolved.
Show resolved Hide resolved
// `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;
}
}
22 changes: 11 additions & 11 deletions index.d.ts
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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[];
};
}

Expand Down
15 changes: 12 additions & 3 deletions lib/intl.ts
Expand Up @@ -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(
lionel-rowe marked this conversation as resolved.
Show resolved Hide resolved
// TODO: remove type assertion after TS lib types updated per https://github.com/microsoft/TypeScript/issues/52946
locale as ConstructorParameters<typeof IntlDateTimeFormat>[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
Expand Down Expand Up @@ -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<typeof IntlDateTimeFormat['supportedLocalesOf']>[0],
// TODO: remove type assertion after Temporal types land in TS lib types
options as globalThis.Intl.DateTimeFormatOptions
);
};

const propertyDescriptors: Partial<Record<keyof Intl.DateTimeFormat, PropertyDescriptor>> = {
Expand Down
9 changes: 9 additions & 0 deletions package.json
Expand Up @@ -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"
Expand All @@ -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 \"$@\"",
Expand Down