Typescript toUpperCase()-konvertering blir ikke akseptert


Jeg har kildetype definert som:

unit: 'hour'|'day'|'week'|'month'

Jeg bruker det som små bokstaver for moment.js-biblioteket. Men jeg trenger det også som store bokstaver for backend-endepunktet. Så min HTTP-metode godtar parameter som

unit: 'HOUR'|'DAY'|'WEEK'|'MONTH'

Men typescript godtar ikke konvertering via toUpperCase i metodekall.

Argument av typen 'string' kan ikke tildeles parameter av typen 'HOUR'|'DAY'|'WEEK'|'MONTH'

Finnes det en elegant løsning i TypeScript som ikke ødelegger statisk typetesting, og samtidig ikke krever at jeg lager en ekstra konverteringshjelpefunksjon (tilpasset toUpperCase)?

Takk for rådene! :)

Svar #1

Du kan utvide deklarasjonen av toUpperCase til å ha en ekstra overbelastning som tar denne spesifikke unionen av streng-litteraltyper og returnerer den store bokstaven av unionstypen. Det finnes ingen ekstra funksjon, bare en ekstra deklarasjon på kompileringstidspunktet:

interface String {
    toUpperCase(this: 'hour'|'day'|'week'|'month') : 'HOUR'|'DAY'|'WEEK'|'MONTH'
}

declare let low: 'hour'|'day'|'week'|'month';
let up = low.toUpperCase(); // typed as "HOUR" | "DAY" | "WEEK" | "MONTH"

Merk

Hvis du er i en modul, må du erklære strengen på nytt i det globale navnerommet:

declare global {
    interface String {
        toUpperCase(this: 'hour' | 'day' | 'week' | 'month'): 'HOUR' | 'DAY' | 'WEEK' | 'MONTH'
    }
}

Svar #2

Avhengig av forrige svar kan du gjøre omfanget av deklarasjonen mer generisk med TypeScript forhåndsdefinerte.

interface String {
  toUpperCase<T extends string>(this: T): Uppercase<T>;
}

Relaterte artikler