Typescript-grensesnitt der nøkkelens navn har en kjent prefiks, men hele nøkkelen er ukjent


Finnes det en måte å definere et grensesnitt på hvor nøklene har en kjent prefiks (added_, removed_), men den fullstendige nøkkelen er ukjent?

For eksempel kan et gyldig objekt være:

{
   name: "",
   added_abc: [1,2,3],
   added_bcd: [2],
   removed_abcd: [4,5],
   removed_xyz: [],
}

Jeg vil sørge for et grensesnitt med:

interface myobject {
   name: string;
   added_*?: number[];
   removed_*?: number[];
}

Svar #1

Når TypeScript 4.4 blir utgitt, vil du kunne utnytte malstrengmønster-literal-indekssignaturer, som implementert i microsoft/TypeScript#44512, og da vil dette fungere:

// TS4.4+
interface MyObject {
  name: string;
  [k: `added_${string}`]: number[];
  [k: `removed_${string}`]: number[];
}

const myObject: MyObject = {
  name: "",
  added_abc: [1, 2, 3],
  added_bcd: [2],
  removed_abcd: [4, 5],
  removed_xyz: [],
} // okay

const myBadObject: MyObject = {
  name: "",
  added_abc: [1, 2, 3],
  addled_bcd: [2], // error!
}

Inntil da finnes det ingen spesifikk type i TypeScript som representerer kravene dine. Du kan bruke generiske hjelpefunksjoner med tekstmaltyper i TS4.1 til TS4.3, men slike funksjoner er mer kompliserte:

// TS 4.1-4.3
const asMyObject = <T extends { name: string } & { [K in keyof T]:
  K extends `added_${string}` | `removed_${string}` ? number[] :
  K extends "name" ? string :
  never }>(t: T) => t;

const myObject2 = asMyObject({
  name: "",
  added_abc: [1, 2, 3],
  added_bcd: [2],
  removed_abcd: [4, 5],
  removed_xyz: [],
}); // okay

const myBadObject2 = asMyObject({
  name: "",
  added_abc: [1, 2, 3],
  addled_bcd: [2], // error!  
});

Lenke til kode på lekeplassen

Relaterte artikler