typescript - parametrar där den ena är enum och den andra är en union av strängar som är giltiga nycklar för detta enum
Jag skriver en ganska enkel sorteringsfunktion för backend-API. Om det inte finns någon sortering returnerar den en tom sträng. Om det finns sortering returnerar den ett värde taget från ett enum baserat på kolumn + några mindre modifieringar. Men jag har problem med typer. sort, när den inte är null, har en sortBy som är T som skickas till denna funktion (union av strängar), detta fungerar okej. Jag vet inte hur jag ska skicka Enum till funktionen där sort.sortBy är en giltig nyckel i det enumet.
type SortState = null | {sortBy: string; sortAsc: boolean; }
const handleSort = <T, K extends T>(sort: SortState, sortEnum: K) => {
if (!sort) {
return '';
}
const name = sort.sortBy as T;
const order = sort.sortAsc;
const newQuery = `${order ? '-' : ''}${order ? sortEnum[name].replaceAll(',', ',-') : sortEnum[name]}`;
return newQuery;
};
enum SortEnum {
bar = 'bar',
foo = 'foo'
}
type TableHeaders = 'foo' | 'bar'
const sortQuery = handleSort<TableHeaders>({sortBy: 'bar', sortAsc: false}, SortEnum)
Svar #1
Med tanke på din implementation och anrop skulle jag vara benägen att göra handleSort() generisk i typen K som motsvarar sortBy-egenskapen av sort-argumentet, vilket också är en nyckel i sortEnum-argumentet. På detta sätt:
const handleSort = <K extends PropertyKey>(
sort: null | { sortBy: K, sortAsc: boolean },
sortEnum: Record<K, string>
) => {
if (!sort) {
return '';
}
const name = sort.sortBy;
const order = sort.sortAsc;
const newQuery = `${order ? '-' : ''}${
order ? sortEnum[name].replaceAll(',', ',-') : sortEnum[name]
}`;
return newQuery;
};
Parametern sortEnum är av typen Record<K, string> som använder Record-hjälptypen för att betyda "en typ med en string-värd egenskap på varje nyckel av typen K". Implementeringen typkontrolleras eftersom kompilatorn förstår att name är av typen K (om sort är sant) och därmed att sortEnum[name] är av typen string.
Låt oss testa samtalssidan:
const sortQuery = handleSort(
{ sortBy: 'bar', sortAsc: false },
SortEnum
); // okay
const sortQuery2 = handleSort(
{ sortBy: 'baz', sortAsc: false },
SortEnum // error!
// ~~~~~~~~ <-- Property 'baz' is missing in type 'typeof SortEnum'
);
Ser bra ut. Kompilatorn är nöjd när sortBy matchar en nyckel i SortEnum, och missnöjd när den inte gör det.
Lekplatslänk till kod
