TypeScript: Les generisk type av verdi i objekt
Jeg har dette grensesnittet:
interface Api {
state: Converter<State>;
water: Converter<Water>;
version: Converter<Versions>;
}
og jeg har en funksjon som heter write
write(name, value);
nå ønsker jeg å oppnå at typen til value skal være den generiske typen til Converter avhengig av den første parameteren (name).
Så hvis jeg kaller write("state", value) -> value burde være State. Det samme gjelder for "water" og "version".
write("state, value); // value should be type of State
write("water", value); // value should be type of Water
write("version", value); // value should be type of Versions
Jeg implementerte den første parameteren på denne måten:
write(name: keyof Api, value: ???)
Jeg oppdaget at jeg kan få den tilsvarende verdien til keyof Api slik:
write<K extends keyof Api>(name: K, value: Api[K])
men det gir meg Converter<State> for "state". Finnes det en måte jeg kan få tilgang til generikken i Converter?
Svar #1
hvis du har tilgang til Converter-grensesnittet/-typen eller hva det nå er, bare utvid det med denne typen
eller opprett en utvidet grensesnitt som dette
interface Converter<T> {
p1: any;
p2: any;
}
interface IExtendedConverter<T> extends Converter<T> {
type: T;
}
interface IApi {
state: IExtendedConverter<string>;
water: IExtendedConverter<number>;
}
const write = <K extends keyof IApi>(name: K, value: IApi[K]['type']) => {
return;
};
const str = write('state', '1'); // here value has to be string
const num = write('water', 1); // here value has to be number
REDIGER basert på spørsmål
en løsning ville være å definere denne parameteren
const extendedConverterState: IExtendedConverter<string> = {
...converter,
type: '',
};
const extendedConverterNumber: IExtendedConverter<number> = {
...converter,
type: 1,
};
const api: IApi = {
state: extendedConverterState,
water: extendedConverterNumber,
};
Dette er på en måte en dum løsning siden du bare ville opprettet denne egenskapen som aldri vil bli brukt.
En annen løsning kan være å lage typeparameter som valgfri
interface IExtendedConverter<T> extends Converter<T> {
type?: T;
}
men denne løsningen vil lage parameteren din i skrivefunksjonen som valgfri (muligens udefinert)
vel kanskje det finnes en bedre løsning for å få tilgang til denne generiske typen. vet ikke
Svar #2
Jeg vet ikke om dette hjelper, siden jeg ikke er sikker på hvordan din Converter-grensesnitt ser ut.
Men med dette:
interface Converter<T> {
converter: T;
}
Og disse grensesnittene for State, Water og Version:
interface State {
state: string;
}
interface Water {
water: string;
}
interface Version {
version: string;
}
Du kan gjøre dette:
function write<K extends keyof Api>(name: K, value: Api[K]["converter"]) {}
write("state", { state: "x" }); // Works
write("water", { state: "x" }); // Argument of type '{ state: string; }' is not assignable to parameter of type 'Water'.
write("water", { water: "x" }); // Works
Men det legger til en egenskap i ditt Converter-grensesnitt.
