我正在尝试使用DDD减少Typescript项目中的一些样板。我的目标是有一种快速的方法来创建一个强类型的Value对象,其中唯一的值是一个有界长度的字符串。
我的第一次尝试是:
type BoundedStringProps = {
value: string;
};
export function makeBoundedString(minLength: number, maxLength: number) {
return class BoundedString extends ValueObject<BoundedStringProps> {
private constructor(props: BoundedStringProps) {
super(props);
}
get value() {
return this.props.value;
}
public static create(props: BoundedStringProps): Result<BoundedString> {
const guardRes = Guard.combine([
Guard.againstNullOrUndefined(props.value, "value"),
Guard.inRange(props.value?.length ?? 0, minLength, maxLength, "value"),
]);
if (!guardRes.succeeded) {
return Result.fail(guardRes.message);
}
return Result.ok(new BoundedString(props));
}
};
}
然后它会像这样使用:
const MyValueObjectName = makeBoundedString(1, 100);
这在某种意义上是有效的,MyValueObjectName现在是一个具有有界长度的类,但它没有被typescript识别为类型,因此将它分配给一个没有"的接口;typeof";不起作用。
const SomeEntityName = makeBoundedString(1, 100);
interface SomeEntityProps = {
name: SomeEntityName; // Value not a type
}
有没有什么可以用尽可能少的代码(最好是一行代码(实现我想要的?
如果没有typeof
,这是行不通的。
当您静态地声明一个类(如class MyClass {}
(时,Typescript会发挥一些作用。它创建了一个名为MyClass
的类型和一个称为MyClass
的值。神奇的是,你似乎有一个东西,类,它在值位置和类型位置都有效。
但这些是不同的东西。
该值是类构造函数,您使用new
调用它来创建实例。那么,类型实际上就是该类实例的类型。它们是相关的,但又不同。
然而,当您动态地声明一个类(如return class ....
(时,这种魔力不会发生。函数返回值,句点。并且值不能用作类型。如果需要值的类型,则必须使用typeof
运算符。
所以,你可以模仿一下:
const SomeEntityName = makeBoundedString(1, 100);
type SomeEntityName = typeof SomeEntityName
但我认为这是最好的。