reactjs - Hur man använder slotLabelFormat med en konstant


Jag försöker ställa in slotLabelFormat-alternativ i ett React TypeScript-projekt

Om slotLabelFormat={{ hour: "2-digit", minute: "2-digit", omitZeroMinute: false, meridiem: "short" }} typescript kompilerade och allt fungerar bra

Men om jag sätter konstant som

const SLOT_LABEL_FORMAT = { hour: "2-digit", minute: "2-digit", omitZeroMinute: false, meridiem: "short" };

och försök ställa

slotLabelFormat={SLOT_LABEL_FORMAT}

TypeScript kompileras inte och har fel

Compiled with problems:

ERROR in src/Calendar/Calendar/components/CalendarView.tsx:119:9

TS2769: No overload matches this call.
  Overload 1 of 2, '(props: CalendarOptions | Readonly<CalendarOptions>): FullCalendar', gave the following error.
    Type '{ hour: string; minute: string; omitZeroMinute: boolean; meridiem: string; }' is not assignable to type 'FormatterInput | FormatterInput[] | undefined'.
      Type '{ hour: string; minute: string; omitZeroMinute: boolean; meridiem: string; }' is not assignable to type 'NativeFormatterOptions'.
        Types of property 'meridiem' are incompatible.
          Type 'string' is not assignable to type 'boolean | "short" | "lowercase" | "narrow" | undefined'.
  Overload 2 of 2, '(props: CalendarOptions, context: any): FullCalendar', gave the following error.
    Type '{ hour: string; minute: string; omitZeroMinute: boolean; meridiem: string; }' is not assignable to type 'FormatterInput | FormatterInput[] | undefined'.
    117 |         allDaySlot={false}
    118 |         locale="uk"
  > 119 |         slotLabelFormat={SLOT_LABEL_FORMAT}
        |         ^^^^^^^^^^^^^^^
    120 |         weekNumberCalculation="ISO" // Makes week calendar to start from monday
    121 |         slotMinWidth={72} // This property doesn't work (Fixed with styles)
    122 |         longPressDelay={50}
If try describe types for const will not expected result

Svar #1

När du skickar objektliteralet som en prop, vet det att behandla det som CalendarOptions och objektets egenskap "meridian" begränsas till literaltypen "short".

När du definierar objektet i förväg, utanför sammanhanget för komponentens prop, härleder TypeScript typen av objektet mer generellt, och typen av "meridian" blir istället string.

Som du kan se från felet:

Type 'string' is not assignable to type 'boolean | "short" | "lowercase" | "narrow" | undefined'.

en godtycklig sträng är inte ett acceptabelt värde för denna egenskap.

Du kan instruera kompilatorn att härleda typen av ditt objekt så snävt som möjligt genom att använda en const-assertion, och då borde det fungera som du vill:

const SLOT_LABEL_FORMAT = { hour: "2-digit", minute: "2-digit", omitZeroMinute: false, meridiem: "short" } as const;

Detta gör att varje strängegenskap blir typad som sitt strängliteralvärde istället för string.