TypeScript mister typeinformation efter spread?
I den følgende kode, hvorfor giver personInvalidAndErrorCaught-tildelingen en TypeScript-fejl (som jeg ville forvente), men personInvalidButErrorUncaught gør ikke? Især da begge linjer transpileres til den samme JavaScript?
TypeScript:
interface Person {
name: string;
}
const person: Person = { name: "name" }
const personInvalidAndErrorCaught: Person = { ...person, invalidKey: "" } // Error as expected: Object literal may only specify known properties, and 'invalidKey' does not exist in type 'Person'.(2322)
const personInvalidButErrorUncaught: Person = { ...person, ...{ invalidKey: "" } } // Why no error? Especially since this line transpiles to the same JS as the line above?
Transpileret JavaScript:
"use strict";
const person = { name: "name" };
const personInvalidButCaught = Object.assign(Object.assign({}, person), { invalidKey: "" });
const personInvalidButUncaught = Object.assign(Object.assign({}, person), { invalidKey: "" });
Billede viser fejl:
Legeplads link
Svar #1
Forskellen er, at du direkte tildeler objektliteralet, der indeholder den ugyldige nøgle, i det tilfælde, der ikke virker, og TypeScript behandler det specielt. Fra beta-dokumentationen (de advarer om, at linket kan blive forældet):
Bemærk, at det givne argument til
createSquareer stavetcolouri stedet forcolor. I almindelig JavaScript fejler denne slags ting stille.Man kunne argumentere for, at dette program er korrekt typet, da
width-egenskaberne er kompatible, der ikke er nogencolor-egenskab til stede, og den ekstracolour-egenskab er ubetydelig.Men TypeScript indtager holdningen, at der sandsynligvis er en fejl i denne kode. Objektliteraler får særlig behandling og undergår kontrol for overskydende egenskaber, når de tildeles andre variabler eller gives som argumenter.
(min fremhævning)
(Der er også den nuværende dokumentation, du fandt.)
I dit andet tilfælde, hvor der ikke er nogen fejl, tildeler du ikke objektet med den overskydende egenskab direkte til variablen, du tildeler wrapper-objektet, som det bliver spredt ind i. Det er en subtil forskel, selvfølgelig, men det er en forskel.
Dette er bare en speciel sag, som TypeScript markerer, fordi når du tildeler litteralen direkte og angiver en ugyldig egenskab, er det sandsynligvis en fejl. Noget mere komplekst behøver ikke at være det.
Det faktum, at spredning ikke udløser denne kontrol, er, som du fandt i en af testene, med vilje:
const a1: A = { ...extra1 }; // spread should not give excess property errors
