typescript - Kan jag använda objektets egenskapsnamn som ett strängvärde i objektet?


Kan jag använda objektets egenskapsnamn som ett strängvärde i objektet? Jag menar att jag vill uppnå detta:

type MyObjectType = /* ... */

const myValidObject: MyObjectType = {
  a: 'a',
  b: 'b'
} // valid object of type MyObjectType

const myInvalidObject: MyObjectType = {
  a: 'a',
  b: 'c'
} // invalid object of type MyObjectType, property b should have value 'b'

Jag har provat något liknande men det fungerar inte:

type MyObjectType = {
  [K: string]: `${K}`
}

Svar #1

Det finns ingen specifik typ MyObjectType i TypeScript som skulle uppfylla dina behov. Istället kan du skapa en generisk typ där typparametern K är unionen av nycklarna i objektet:

type MyObjectType<K extends PropertyKey> =
  { [P in K]: P }

Men du vill förmodligen inte behöva skriva ut MyObjectType<"a" | "b"> själv. Det betyder att du kommer vilja ha en generell hjälpfunktion för att sluta typargumentet åt dig:

const myObjectType =
  <K extends PropertyKey>(o: MyObjectType<K>) => o;

Nu, istället för const o: MyObjectType={⋯}, skriver du const o=myObjectType({⋯}). Det är ungefär lika mycket arbete för dig, men det ger dig det önskade beteendet:

const myValidObject = myObjectType({
  a: 'a',
  b: 'b'
});
// const myValidObject: MyObjectType<"a" | "b">

const myInvalidObject = myObjectType({
  a: 'a',
  b: 'c' // error
  // Type '"c"' is not assignable to type '"b"'.
});
// const myInvalidObject: MyObjectType<"a" | "b">

Playground-länk till kod

Relaterade artiklar