Määritä lista valinnaisista avaimista Typescript Recordille


Haluan kirjoittaa objektin, jolla voi olla vain avaimet 'a', 'b' tai 'c'.

Joten voin tehdä sen seuraavasti:

Interface IList {
    a?: string;
    b?: string;
    c?: string;
}

Ne ovat kaikki valinnaisia! Nyt pohdin, voisiko tämän kirjoittaa Record-tunnisteella yhdellä rivillä

type List = Record<'a' | 'b' | 'c', string>;

Ainoa ongelma on, että kaikki avaimet täytyy määritellä. Joten päädyin siihen, että

type List = Partial<Record<'a' | 'b' | 'c', string>>;

Tämä toimii, mutta voin kuvitella, että on parempi tapa tehdä tämä ilman Partialia. Onko olemassa muuta tapaa tehdä avaimet valinnaisiksi Recordin sisällä?

Vastaus #1

Record-tyypin jäsenten valinnaisuutta ei voi määrittää. Ne ovat määritelmän mukaan pakollisia

type Record<K extends keyof any, T> = {
    [P in K]: T; // Mapped properties are not optional, and it's not a homomorphic mapped type so it can't come from anywhere else.
};

Voit määritellä oman tyypin, jos tämä on sinulle yleinen tilanne:

type PartialRecord<K extends keyof any, T> = {
  [P in K]?: T;
};
type List =  PartialRecord<'a' | 'b' | 'c', string>

Tai voit määritellä PartialRecord-tyypin myös käyttämällä ennalta määriteltyjä kartoitettyjä tyyppejä:

type PartialRecord<K extends keyof any, T> =  Partial<Record<K, T>>

Vastaus #2

Voit luoda osittaisen version List-tyypistäsi:

type PartialList = Partial<List>;

Ja voisit tehdä kaiken yhdellä rivillä, jos et halua välimuotoa:

type PartialList = Partial<Record<'a' | 'b' | 'c', string>>;

Saatat päättää, että lopulta kaikkein ilmaisevinta tulevalle itsellesi on:

type List = {
    a?: string;
    b?: string;
    c?: string;
}

Vastaus #3

Näyttää siltä, että uusissa TypeScriptin versioissa voit tehdä seuraavaa

type YourUnion = 'a' | 'b' | 'c';   
type ObjectWithOptionalKeys = Partial<Record<YourUnion, string>>
const someObject: ObjectWithOptionalKeys {
  a: 'str', // works
  b: 1 // throws
}
// c may not be specified at all

Vastaus #4

Sen voi myös tehdä tällä tavalla:

type List = { [P in 'a' | 'b' | 'c']?: string }; // The `?` makes the keys optional

Esimerkkejä:

const validList1: List = {
  a: 'hi'
}

const validList2: List = {
  b: 'hi',
  c: 'there'
}

const validList3: List = {
  a: 'oh',
  b: 'hi',
  c: 'there'
}

Aiheeseen liittyviä artikkeleita