typescript - Hvordan sjekke om egenskapen min finnes i typen


Så vidt vi vet tillater TypeScript oss å deklarere delvis typer, men hva når vi skal sjekke om min egenskap er i keyof Type. La oss se

interface Car {
   Brand: string;
   Model: string;
}

type KeyofCar = keyof Car; // Brand, Model

if('Brand' is in KeyofCar) {
   something...
} // I know it doesn't work but it is pseudocode

Er det noen måte å finne det ut på?

Svar #1

Jeg er ikke sikker på hva du prøver å oppnå her. I spørsmålet ditt vet du på kompileringstidspunktet at 'Brand' er i keyof Car. Så hvorfor skulle du sjekke det?

Jeg kunne forestille meg å prøve å gjøre noe slikt hvis typen ikke er helt kjent, som i et typeargument...

function<T>(foo: T) {
  // this is not possible because keyof does not exist in runtime contexts
  if('bar' in keyof T) {
    // do something...
  }
}

Jeg vil si at du ikke ville prøvd å løse problemet ved å sammenligne noe med keyof T. Prøv i stedet å gjøre noe slik som dette

interface Car {
  Brand: string;
  Model: string;
}

interface Bus {
  Passengers: number;
  Color: string;
}

function(foo: Car | Bus) {
  if('Brand' in foo) {
    // foo is a Car
  } else {
    // foo is a Bus
  }
}

Hvis du virkelig vil gjøre noe med nøklene, kunne du gjort noe slik som dette

type CarKey = keyof Car;
const carKeys: CarKey[] = ['Brand', 'Model'];

function(key: string) {
  if(carKeys.includes(key)) {
    // do thing
  }
}

Eller for å være enda tryggere på at du har hver nøkkel

type CarKey = keyof Car;
const carKeys = Object.keys({
    Brand: null, 
    Model: null
} satisfies Record<CarKey, null>) as Array<keyof Car>;

function isKeyOfCar(key: string): key is CarKey {
    return carKeys.includes(key);
}

På den måten, hvis Car-typen endres over tid, vil du vite om disse nøklene må oppdateres.

Svar #2

Per dette øyeblikket finnes det ingen måte å sjekke dette på under kjøring kun ved å bruke Typescript-mekanismer. Men en slags stygg løsning du kan gjøre er å lage en Record og deretter hente nøklene fra den.

interface Car {
   Brand: string;
   Model: string;
}

const carRecord: Record<keyof Car, boolean> = {
  Brand: true,
  Model: true
}

if (carRecord['Brand']) {
  something...
}

Grunnen til at du gjør en Record er fordi hver gang du endrer grensesnittet, må du også endre Record. Ellers vil Typescript kaste kompilasjonsfeil. Som et minimum sikrer dette at sjekken forblir konsekvent etter hvert som Car-grensesnittet vokser.

Relaterte artikler