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'
}
