Hur skapar man en typ från en annan typ som har en specifik egenskap med en annan typ i TypeScript?


Jag har den här typen:

type Period = 'Monthly' | 'Yearly'
type Cycle = {
    period: Period,
    price: number
}

Och jag vill få följande typ (i princip, tillåta att period kan vara en tom sträng):

type Period = 'Monthly' | 'Yearly'
type EditableCycle = {
    period: Period | '',
    price: number
}

Jag tänkte på något sådant här påhittat syntax:

type EditableCycle = Extend<Cycle, { period: '' }>

Hur kan jag uppnå det?

Anledningen är att jag vill att användaren ska kunna låta bli att välja någon period när de redigerar (därför kan perioden vara en tom sträng) men efter att ha validerat den är jag säker på att perioden kommer att innehålla en giltig Period.

observera: den verkliga typen är mycket mer komplicerad än Cycle, och involverar arrayer och liknande saker, detta är ett nedskuret exempel.

Svar #1

Du kan använda Omit-verktygstypen för att åsidosätta period-fältet:

type Period = 'Monthly' | 'Yearly'
type Cycle = {
    period: Period,
    price: number
}

type EditableCycle = Omit<Cycle, "period"> & {
  period: Period | ''
}

const editableCycle: EditableCycle = {
  period: '',
  price: 5
}

Om denna lösning fungerar för dig kan du gå ett steg längre och skapa din egen Override-typ på detta sätt:

type Period = 'Monthly' | 'Yearly'
type Cycle = {
    period: Period,
    price: number
}

type Override<T, K> = Omit<T, keyof K> & K

type EditableCycle = Override<Cycle, {
  period: Period | ''
}>

const editableCycle: EditableCycle = {
  period: '',
  price: 5
}

Jag hoppas att du finner detta svar hjälpsamt.

François

Svar #2

Kanske kan du definiera det på följande sätt:

type Period = 'Monthly' | 'Yearly'
type Cycle = {
    period: Period,
    price: number
}

type Editable<T> =  {
  [K in keyof T]: T[K] extends string? (T[K] | '') : T[K];
};

type EditableCycle = Editable<Cycle>; // -->  period: "" | Period;