Как вызвать функцию из конструктора ImmutableJS Record - PullRequest
0 голосов
/ 01 мая 2018

Я заменил многие / большинство моих объектов машинописи на Неизменяемые записи для некоторого уровня безопасности / защищенности / теплоты и нечеткости, но я только что заметил, что мой конструктор теперь сломан.

Первоначально я автоматически создавал новые UUID в своем конструкторе в качестве значения по умолчанию, но с записями ImmutableJS - это поведение не работает.

Я понимаю, почему, но я не совсем уверен, каков правильный обходной путь - но я чувствую, что это либо действительно сложно, либо глупо просто.

import { Record } from "immutable";
import uuid from "uuid";

const tagDefaults: TagParams = {
    depth: 0,
    id: "tag::" + uuid.v4(),
    name,
    order: 0,
};

interface TagParams {
    name: string;
    order: number;
    depth: number;
    id: string;
}

export class Tag extends Record(tagDefaults) { }

Создание этого начального tagDefaults - это то, что создает первый UUID - после чего все последующие новые Tag() используют один и тот же идентификатор.

Есть ли простой способ вызывать функцию для каждого конструктора? Я попытался переопределить конструктор (this.id = uuid.v4()), но это фактически заставляет меня упасть в Webpack.

ОБНОВЛЕНИЕ: 8 июня 2018 года

Используя предоставленный ответ @mpontus, вот обновленный пример, показывающий, что любой из вариантов может работать.

import { Record, Set } from "immutable";
import uuid from "uuid";

const tagDefaults: TagParams = {
    depth: 0,
    id: "",
    name,
    order: 0,
};

interface TagParams {
    name: string;
    order: number;
    depth: number;
    id: string;
}

export class Tag extends Record(tagDefaults) {
    constructor(props: Partial<TagParams> = {}) {
        // Option A - Works
        if (!props.id) {
            props.id = uuid.v4();
        }

        super(props);

        // Option B - Works
        // if (!this.id) {
        //     return this.set("id", uuid.v4());
        // }
        // return this;
    }
}

describe("Given a Tag", () => {
    describe("When constructed", () => {
        test("It should contain a unique id", () => {
            const tag1 = new Tag();
            const tag2 = new Tag({});
            const tag3 = new Tag({ depth: 1, name: "hello", order: 10 });
            const tag4 = new Tag({ id: "tag4Id" });
            const tags = Set([tag1, tag2, tag3, tag4].map((t) => t.id));
            expect(tags.size).toBe(4);
            console.log([tags]);
        });
    });
});

1 Ответ

0 голосов
/ 09 мая 2018

Вы не можете выполнить то, что вы хотите, используя значения по умолчанию.

Ваша попытка переопределить конструктор тегов была удачной, но вы должны переопределить значения, входящие в конструктор:

const tagDefaults = {
    depth: 0,
    id: "",
    name: "",
    order: 0,
};

class Tag extends Record(tagDefaults) {
    constructor(values) {
        const finalValues = { ...values };

        if (finalValues.id === undefined) {
            finalValues.id = uuid.v4();
        }

        super(finalValues);
    }
}

Кроме того, вы можете вернуть другой экземпляр записи из конструктора, но я не уверен, что TypeScript примет это.

const { Record } = require("immutable");
const uuid = require('uuid');

const tagDefaults = {
    depth: 0,
    id: undefined,
    name: "",
    order: 0,
};

class Tag extends Record(tagDefaults) {
    constructor(values) {
        super(values);

        if (this.id === undefined) {
            return this.set('id', uuid.v4());
        }

        return this;
    }
}
...