Typescript - Hur man skapar en typ med samma egenskaper som ett gränssnitt, men med olika egenskapstyper
Jag skapar en fråga-byggare. Jag har datamodeller som ser ut så här:
export interface SalesOrder {
id: number
customerName: string;
date: Date;
}
I min frågebyggare vill jag att columns ska se ut ungefär så här:
{
id: 'salesOrder.id',
customerName: 'customer.name',
date: 'salesOrder.date',
}
Jag försöker lista ut hur jag kan typsätta Columns-objektet generiskt så att det har alla nycklar från modellen, men alla typer kommer att vara strängar. Så då skulle jag kunna deklarera det som const columns: Columns<SalesOrder> och det skulle förstå att objektet måste ha alla samma nycklar som i SalesOrder-modellen, men med alla värden som string.
Jag försökte detta:
export interface Columns<T> {
[alias: keyof T]: string;
}
Men det klagar på delen keyof T och säger "En indexsignatur-parameter typ måste antingen vara 'string' eller 'number'."
Svar #1
Slutet på det felmeddelandet borde ha varit:
Överväg att använda en mappad objekttyp istället.
Se dokumentationen om mappade typer.
Här är vad det betyder:
export type Columns<T> = {
[alias in keyof T]: string;
}
Det behöver vara en type, eftersom detta faktiskt är en mappad typ. Den går igenom alla möjligheter av keyof T och utvärderar varje medlem av den unionen individuellt. Detta stöds egentligen inte i gränssnitt.
Och [key: MyType] är en indexsignatur. Det säger att för vilken MyType som helst finns ett värde av en konsekvent typ. Där [key in MyType] definierar nycklarna i en mappad typ.
Lekplats
Alternativt kan du prova Record-typen.
export type Columns<T> = Record<keyof T, string>
Lekplats
