gpt4 book ai didi

typescript - 有没有一种优雅的方法可以在 typescript 中拥有值(value)对象?

转载 作者:行者123 更新时间:2023-12-05 02:11:22 24 4
gpt4 key购买 nike

问题

为了验证目的,我想在我的系统核心中有一些值对象。这些值对象可以是类:

class UserName {
readonly value: string;

constructor(value: string) {
this.value = value.trim();
if (this.value === '') {
throw new Error('Empty value');
}
}
}

// and use it

userService.updateName({id: 1, name: new UserName('Maxim')});

但它不能很好地工作,因为每个人都可以调用服务而无需实例化类,因此无需验证:

userService.updateName({id: 1, name: {value: INVALID_NAME});

我的解决方案

我有一个接口(interface)和实用函数来创建不方便手动创建的对象:

interface ValueObject<T extends string, U> {
readonly type: T;
readonly value: U;
readonly DO_NOT_CREATE_MANUALLY: 'DO NOT CREATE THIS MANUALLY!',
}

function ValueObject<T extends string, U>(type: T, value: U): ValueObject<T, U> {
return {
type,
value,
DO_NOT_CREATE_MANUALLY: 'DO NOT CREATE THIS MANUALLY!',
};
}

我有一个值对象和实用函数的接口(interface):

interface UserName extends ValueObject<'UserName', string> {}

function UserName(value: string): UserName {
value = value.trim();
if (value === '') {
throw new Error('Empty value');
}

return ValueObject('UserName', value);
}

我是这样使用的:

userService.updateName({id: 1, name: UserName('Maxim')});

效果很好。没有人会写:

userService.updateName({
id: 1,
name: {
value: INVALI_VALUE,
type: 'UserName',
DO_NOT_CREATE_MANUALLY: 'DO NOT CREATE THIS MANUALLY!',
},
});

问题

有没有更优雅的方式在没有 DO_NOT_CREATE_MANUALLY 的情况下在 typescript 中拥有值对象?

最佳答案

进一步充实@titian 的评论...

考虑以下类:

class UserName {
public readonly value: string;
constructor(value: string) {
if (value === '') {
throw new Error('Empty value');
}
this.value = value;
}
}

根据Typescript type compatibility documentation ,任何具有 value: string 属性的对象都将与此类的实例兼容。这是您要避免的 - 您要确保传递给 userService.updateName 的任何类似于 UserName 的对象实际上是一个 UserName对象。

解决方案是向类添加一个私有(private)属性,这样任何 UserName 类的对象也必须具有该私有(private)属性:

class UserName {
public readonly value: string;
private readonly is_nominal: boolean = true;
constructor(value: string) {
if (value === '') {
throw new Error('Empty value');
}
this.value = value;
}
}

现在,如果有人做了以下事情:

userService.updateName({ id: 1, value: { value: 'James T Kirk' } })`

Typescript 会报错,因为 { value: 'James T Kirk' } 缺少私有(private) is_nominal 属性。

但是,有一种更简单(恕我直言,更简洁)的方法来添加私有(private)字段:将值设为私有(private)并添加访问器。

class UserName {
private readonly _value: string;
constructor(value: string) {
if (value === '') {
throw new Error('Empty value');
}
this._value = value;
}

get value() { return this._value; }
}

关于typescript - 有没有一种优雅的方法可以在 typescript 中拥有值(value)对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57599393/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com