angular - Typescript spread operator na objektu s metodom


U mom Angular projektu imam objekt koji sadrži polja tip i status. Status se može mijenjati ovisno o tipu. Netko bi mogao reći da je ovo loš dizajn, ali za sada je tako. Poanta je da ne mogu koristiti operator spread na ovom objektu, jer kompajler kaže Property 'getStatusList' is missing in type ...

Pojednostavio sam klasu, ali izgledalo bi otprilike ovako:

export class Foo {
    constructor(
        public type: number,
        public status: number
    ) { }

    getStatusList(): string[] {
        switch (this.type) {
            case 3: {
                return ['Off', 'Interval', 'On Hold']
            }

            default: {
                return ['Off', 'On']
            }
        }
    }
}

Ovo je s TypeScript 2.9.2 i Angular CLI 6.1.1

Kod ispod bi izazvao grešku, ali dok sam pisao primjer koda u TypeScript playgroundu, pomislio sam da možda trebam koristiti Object.assign. Iako sam i dalje mislio da jednostavno mogu prebrisati neka svojstva objekta koristeći spread operator?

const oldFoo: Foo = new Foo(3, 5);
console.log('old status: ', oldFoo.status);

const newFoo: Foo = { ...oldFoo, type: 1, status: 7 };
console.log('new status: ', newFoo.status);

Odgovor #1

Kada koristite operator širenja u literalima objekata, nećete dobiti objekt iste klase kao izvorni. Iz dokumentacije:

[Operator širenja] kopira vlastita enumerabilna svojstva s danog objekta na novi objekt.

Plitko kloniranje (izuzimajući prototip) ili spajanje objekata sada je moguće korištenjem kraće sintakse od Object.assign().

Dakle, vi samo „plitko klonirate“ oldFoo. Propustit ćete sve što je na prototipu, poput metoda. Ako želite imati stvarni Foo objekt, vjerojatno biste trebali napraviti novu instancu. Nakon što je napravite, možete koristiti Object.assign() za postavljanje više svojstava odjednom, ali ako ionako koristite konstruktor, pretpostavljam da biste trebali odmah proslijediti prave parametre konstruktoru.

Možete umjesto toga kopirati prototip:

const newFoo  = { ...oldFoo, type: 1, status: 7 } as Foo;
Object.setPrototypeOf(newFoo, Object.getPrototypeOf(oldFoo));

i ovo bi vjerojatno moglo funkcionirati, ali petljati s prototipovima nije nešto što bih shvaćao olako.

Nadam se da to pomaže. Sretno!

Povezani članci