Typescript Array[T] aksepterer {..T} som gyldig type
Dette bet meg da jeg brukte useState<Options[]> som en React-hook, når jeg skrev {...options} i stedet for [...options], jeg fant det først ut da jeg prøvde å få tilgang til .map av "array" (objekt) og fikk en TypeError. La meg gi deg et eksempel som kan klargjøre spørsmålet mitt:
interface Option {
title: string;
isSelected?: boolean;
}
function myFunc(options: Option[]): void {}
const options: Option[] = [{title: 'Male', isSelected: true}, {title: 'Female'}, {title: 'Other'}];
const options2 = {...options};
myFunc(options);
myFunc(options2); // why isn't this an error ?
Svar #1
Dette ser faktisk ut til å være et problem med Typescript selv:
let c: number[] = { ...[0, 1, 2] }; // compiles
c.fill(0) // runtime error
let d: number[] = Object.assign({}, [0, 1, 2]); // compiles
d.fill(0) // runtime error
Videre kompilerer dette også og krasjer under kjøring:
class E {
method() { }
}
let e: E = Object.assign({}, new E)
e.method() // runtime error
PG
Jeg antar at dette er fordi Object.assign er deklarert som
assign<T, U>(target: T, source: U): T & U;
som er feil, siden det assign returnerer faktisk ikke utvider U. Returtypen til assign bør være noe som T & OwnProperties<U>, men dette er for øyeblikket ikke mulig, se
- https://github.com/microsoft/TypeScript/issues/28801
- https://github.com/microsoft/TypeScript/issues/9726
Svar #2
Leker rundt på TypeScript-lekeplassen, det ser ut til at TypeScript mener options2 er definert som:
const options2: {
[x: number]: Option;
length: number;
toString(): string;
toLocaleString(): string;
pop(): Option | undefined;
push(...items: Option[]): number;
concat(...items: ConcatArray<Option>[]): Option[];
concat(...items: (Option | ConcatArray<...>)[]): Option[];
... 24 more ...;
[Symbol.unscopables](): {
...;
};
}
Så det ser faktisk ut som et array av typen Option Option[]. Men spread-operatoren kopierer faktisk ikke Array-prototypemedlemmer, og det nye objektet er definitivt ikke et array. Jeg vil si at dette er en feil i TypeScript-typesystemet.
