TypeScript: Missing specific types in DateTimeFormatOptions

TypeScript Version: 3.7.3

Search Terms: Intl.DateTimeFormat, DateTimeFormatOptions, date format types

Code

// A *self-contained* demonstration of the problem follows...
// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp,
(See below)

DateTimeFormatOptions interface missing specific types. https://github.com/microsoft/TypeScript/blob/408b17649a1197a52f68fcb49b8c2f1eeac13668/src/lib/es5.d.ts#L4253-L4267

Expected behavior: I would expect the types to match what’s listed here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat

  interface DateTimeFormatOptions {
        localeMatcher?: 'lookup' | 'best fit';
        weekday?: 'long' | 'short' | 'narrow';
        era?:  'long' | 'short' | 'narrow';
        year?: 'numeric' | '2-digit';
        month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';
        day?: 'numeric' | '2-digit';
        hour?: 'numeric' | '2-digit';
        minute?: 'numeric' | '2-digit';
        second?: 'numeric' | '2-digit';
        timeZoneName?: 'long' | 'short';
        formatMatcher?: 'basic' | 'best fit';
        hour12?: boolean;
        timeZone?: string; // this is more complicated than the others, not sure what I expect here
    }

Actual behavior:

 interface DateTimeFormatOptions {
        localeMatcher?: string;
        weekday?: string;
        era?: string;
        year?: string;
        month?: string;
        day?: string;
        hour?: string;
        minute?: string;
        second?: string;
        timeZoneName?: string;
        formatMatcher?: string;
        hour12?: boolean;
        timeZone?: string;
    }

Playground Link:

Related Issues: Couldn’t find any

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 34
  • Comments: 19 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Running into this issue for dateStyle and timeStyle options as well.

Until this gets fixed you can extend the TypeScript definition for DateTimeFormatOptions by writing the following code in your project’s root index.d.ts file

declare namespace Intl {
  interface DateTimeFormatOptions {
    dateStyle?: 'full' | 'long' | 'medium' | 'short';
    timeStyle?: 'full' | 'long' | 'medium' | 'short';
  }
}

Running into this issue for dateStyle and timeStyle options as well.

I wonder if these are even related. Should we create a separate issue for that? Because those two properties are just missing entirely.

We don’t like to replace basic TS declares unless necessary, so we extend the base. For that reason I just created a complete type from the MDN docs.

/**
 * Better DateTimeFormatOptions types
 * 
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat for representation details
 */
export interface DateTimeFormatOptions extends Intl.DateTimeFormatOptions {
  localeMatcher?: 'best fit' | 'lookup';
  weekday?: 'long' | 'short' | 'narrow';
  era?:  'long' | 'short' | 'narrow';
  year?: 'numeric' | '2-digit';
  month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';
  day?: 'numeric' | '2-digit';
  hour?: 'numeric' | '2-digit';
  minute?: 'numeric' | '2-digit';
  second?: 'numeric' | '2-digit';
  timeZoneName?: 'long' | 'short';
  formatMatcher?: 'best fit' | 'basic';
  hour12?: boolean;
  /**
   * Timezone string must be one of IANA. UTC is a universally required recognizable value
   */
  timeZone?: 'UTC' | string;
  dateStyle?: 'full' | 'long' | 'medium' | 'short',
  timeStyle?: 'full' | 'long' | 'medium' | 'short',
  calendar?: 'buddhist' | 'chinese' | ' coptic' | 'ethiopia' | 'ethiopic' | 'gregory' | ' hebrew' | 'indian' | 'islamic' | 'iso8601' | ' japanese' | 'persian' | 'roc',
  dayPeriod?: 'narrow' | 'short' | 'long',
  numberingSystem?: 'arab' | 'arabext' | 'bali' | 'beng' | 'deva' | 'fullwide' | ' gujr' | 'guru' | 'hanidec' | 'khmr' | ' knda' | 'laoo' | 'latn' | 'limb' | 'mlym' | ' mong' | 'mymr' | 'orya' | 'tamldec' | ' telu' | 'thai' | 'tibt',
  hourCycle?: 'h11' | 'h12' | 'h23' | 'h24',
  /**
   * Warning! Partial support 
   */
  fractionalSecondDigits?: 0 | 1 | 2 | 3
}

Would be a breaking change; we’ll have to discuss.

I’d love to see this discussed, or move forward. To me, moving runtime exceptions out of js into hard compile-time errors in typescript is one of the strongest points of typescript to begin with.

Here’s a breaking change:

function makeOptions(matcher: string): DateTimeFormatOptions {
  return {
    year: 'numeric',
    formatMatcher: matcher
  }
}

The author of makeOptions will have to propagate the stricter type of formatMatcher out, possibly breaking its consumers.

It appears to be available if you’re targeting ES2020. The TS Playground demo passes type checking if I change the target to ES2020.

This issue can be closed. As of TS 4.2 these types on Intl.DateTimeFormatOptions use unions of strings where possible per;

https://github.com/microsoft/TypeScript/blob/v4.3.5/src/lib/es5.d.ts#L4332-L4346 and https://github.com/microsoft/TypeScript/blob/v4.3.5/src/lib/es2020.intl.d.ts#L280-L288

Note that you will need to target es2020 or otherwise add it to your lib for the properties defined in es2020.intl.d.ts to be present

I don’t have any other dependencies in my project. I’m only using VS Code and setting it to use typescript v4.2.3.

Would be a breaking change; we’ll have to discuss.