Инициализация объектов TypeScript только с их спецификациями класса c с использованием частичных - PullRequest
0 голосов
/ 26 января 2020

Рассмотрим следующий пример:

const assign = <T, K extends keyof T>(...args: T[]): T =>
    args.reduce((result, current) =>
        (Object.keys(current) as K[]).reduce((target, key) => {
            target[key] = current[key];
            return target;
        }, result)
        , args[0]);

class Base {
    str1: string = '';
    str2: string = '';

    constructor(data: Partial<Base>) {
        assign(this, data);
    }
}

class Derived extends Base {
    str3: string = '';

    constructor(data: Partial<Derived>) {
        super(data);
        Object.assign(this, data);
    }
}

const derivedObj = new Derived({ str1: 'text', str3: 'new prop' })
const baseObject = new Base(derivedObj);

console.log(baseObject);
// Outputs:
// Data { "str1": "text", "str2": "", "str3": "new prop" } 

Базовый класс содержит меньше свойств, чем производный класс. Конструктор базового класса принимает Partial<Base>, который также совместим с типом Partial<Derived>. Это приводит к тому, что посторонние свойства назначаются объекту базового класса при передаче объекта типа Partial<Derived>.

. Есть ли способ инициализировать объект базового класса только с указанным классом c свойства (str и str2 и , а не str3)?

PS: На GitHub и здесь есть много похожих обсуждений. До сих пор я не нашел ни одного, который решает эту проблему.

1 Ответ

1 голос
/ 26 января 2020

Это работает:

const assign = <T, K extends keyof T>(...args: T[]): T =>
    args.reduce((result, current) =>
        (Object.keys(args[0]) as K[]).reduce((target, key) => {
            if (current[key] !== undefined) target[key] = current[key];
            return target;
        }, result)
    , args[0]);

Посмотри на это Детская площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...