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.

Relaterte artikler