Open5

TypeScript で値オブジェクトを表現したい

山とコード山とコード

模索中...

abstract class ValueObject<T> {
    protected readonly value: T;

    protected constructor(value: T) {
        this.value = Object.freeze(value);
    }
}

class MountainId extends ValueObject<number> {
    constructor(value: number) {
        super(value);
    }

    public static create(value: number): MountainId {
        if (Number.isInteger(value) === false && value < 0) {
            throw new Error('Mountain id must be a positive integer.');
        }

        return new MountainId(value);
    }

    public getValue(): number {
        return this.value;
    }
}

class MountainName extends ValueObject<string> {
    constructor(value: string) {
        super(value);
    }

    public static create(value: string): MountainName {
        if (value.length < 0 || value.length > 20) {
            throw new Error('Mountain name must be at least 1 and no more than 20 characters.');
        }

        return new MountainName(value);
    }

    public getValue(): string {
        return this.value;
    }
}

type MountainEntity = {
    id: number;
    name: string;
}

type MountainProps = {
    id: MountainId;
    name: MountainName;
};

class Mountain {
    public readonly id: MountainId;
    public readonly name: MountainName;

    protected constructor(props: MountainProps) {
        this.id = props.id;
        this.name = props.name;
    }

    static from(entity: MountainEntity) {
        return new Mountain({
            id: MountainId.create(entity.id),
            name: MountainName.create(entity.name)
        });
    }
}

const mountain = Mountain.from({
    id: 1,
    name: 'Mt.Fuji'
});
console.log(mountain.name.getValue());