typescript - Kartleggings-type av medlem av tuple
Jeg prøver å lage en kartlagt tuple som går ned til typen til et medlem:
export type Argument<T = unknown> = {
value: T;
};
export type TypesOf<T extends Argument[]> = {[Index in keyof T]: T[Index]["value"]};
Så, TypesOf<[{value: number}, {value: string}]> bør gi [number, string].
Men jeg får denne feilen:
Type '"value"' cannot be used to index type 'T[Index]'.
REDIGER :
Bonusspørsmål etter å ha brukt @jcalz sin løsning:
const tuple = [{value: 1}, {value:"foo"}] as const;
type V = TypesOf<typeof tuple>;
Jeg får feil:
Type 'readonly [{ readonly value: 1; }, { readonly value: "foo"; }]' does not satisfy the constraint 'Argument<unknown>[]'.
The type 'readonly [{ readonly value: 1; }, { readonly value: "foo"; }]' is 'readonly' and cannot be assigned to the mutable type 'Argument<unknown>[]'.
Svar #1
Implementeringen av TypesOf som du presenterer fungerer, i den forstand at TypesOf<[{value: number}, {value: string}]> faktisk evaluerer til [number, string]. Kartlagte typer på arrays og tuples resulterer i arrays og tuples.
Men det er et problem, rapportert i microsoft/TypeScript#27995 hvor kompilatoren ikke skjønner at innenfor den mappegte typen implementering {[I in keyof T]: ...T[I]...} vil I kun ende opp med å være de numerisk-lignende indeksene. Den tror at kanskje I vil være ting som "push" og "pop", og derfor kan ikke T[I] antas å være av typen Argument:
export type TypesOf<T extends Argument[]> =
{ [I in keyof T]: T[I]["value"] };
// -----------------> ~~~~~~~~~~~~~
// Type '"value"' cannot be used to index type 'T[I]'.
Antagelig er dette grunnen til at du stilte dette spørsmålet i utgangspunktet. GitHub-problemet er listet som en feil, men det har vært åpent lenge, og det er ikke klart om noe vil skje her.
I slike tilfeller pleier jeg å bruke Extract<T, U>-verktøystypen for å hjelpe med å overbevise kompilatoren om at en type kan tildeles en annen. Hvis du har typen T som du vet kan tildeles U, men kompilatoren ikke gjør det, kan du bruke Extract<T, U> i stedet for T. Når T spesifiseres senere, vil Extract<T, U> evaluere til kun T hvis du har rett om tildelbarheten. Og Extract<T, U> vil bli sett av kompilatoren som tildelbar til både T og U.
I vårt tilfelle vet vi at T[I] kan tilordnes til Argument, men kompilatoren gjør det ikke. Så følgende midlertidige løsning ved å bruke Extract<T[I], Argument> vil undertrykke kompilatorfeilen uten å påvirke outputen av TypesOf:
export type TypesOf<T extends Argument[]> =
{ [I in keyof T]: Extract<T[I], Argument>["value"] }; // no error
type Z = TypesOf<[{ value: number }, { value: string }]>;
// type Z = [number, string]
Ser bra ut!
Lenke til kode for lekeplass
