javascript - Cum să copiezi structura unui tip generic într-un alt generic în TypeScript?
Imaginează-ți că avem următorul tip de intrare:
interface Input {
name: string;
heightCm: number;
dob: Date;
}
Aș dori să scriu o funcție care poate produce următorul tip de ieșire bazat pe această intrare:
interface Output {
name: boolean;
heightCm: boolean;
dob: boolean;
}
Cu alte cuvinte, o funcție care copiază structura de intrare și returnează acea structură ca ieșire, setând toate valorile ca booleeni.
Semnătura funcției ar arăta cam așa:
interface GenericMap<T> {
[key: string]: T;
}
type InputToOutput<In, Out extends GenericMap<boolean>> = (input: In) => Out;
Dacă tipul proprietății Input era inițial un șir de caractere, marchează acea proprietate ca true, altfel marchează ca false.
De exemplu, funcția ar produce următorul rezultat bazat pe Input de mai sus:
{
name: true,
heightCm: false,
dob: false
}
Dar, cel mai important, trebuie să fie sigur din punct de vedere al tipului, astfel încât să pot primi intellisense pe obiectul rezultat.
Ajutorul este foarte apreciat!
Răspuns #1
Cred că vrei doar un tip mapat care să seteze tipul fiecărei proprietăți la boolean?
type GenericMap<T> = {
[K in keyof T]: boolean
}
Pe care l-ați folosi astfel:
interface Input {
name: string;
heightCm: number;
dob: Date;
}
type Output = GenericMap<Input>
// Output is
// {
// name: boolean;
// heightCm: boolean;
// dob: boolean;
// }
Teren de joacă
Ca o îmbunătățire (potențială), ai putea chiar să verifici pentru string în acest alias de tip și să returnezi true sau false, mai degrabă decât boolean.
type GenericMap<T> = {
[K in keyof T]: T[K] extends string ? true : false
}
Care ar genera acest tip în schimb:
type Output = GenericMap<Input>
// {
// name: true;
// heightCm: false;
// dob: false;
// }
Răspunsul #2
Am reușit să ating ceea ce vrei:
interface Input {
name: string;
heightCm: number;
dob: Date;
}
type Out<In> = { [key in keyof In]: In[key] extends string ? true : false }
type InputToOutput<In> = (input: In) => Out<In>;
type Output = Out<Input>;
const clone: InputToOutput<Input> = input => output;
const input: Input = { name: 'foo', heightCm: 3, dob: new Date };
const output: Output = clone(input);
Care oferă următorul rezultat la trecerea mouse-ului peste tipul Output:
const output: {
name: true;
heightCm: false;
dob: false;
}
