因此,我正在尝试在typescript中实现"Options Object“,我读到的typescript是Java Builder模式的替代方案。
我知道我可以使用builder,但它的实现似乎比"Options Object“复杂得多,后者用更少的代码提供了类似的功能。
这是我想要实现的目标:
class OptionsObject {
private readonly name : string;
private readonly no? : number;
constructor(o : OptionsObject){
this.name = o.name;
this.no = o.no;
}
uradi() : void{
console.log(`Number is ${this.no} and name is ${this.name}`);
}
}
const p = new OptionsObject({
name:"asd",
no:11
} as unknown as OptionsObject); //works but no type-safety
p.uradi();
//standard java builder
//const p2 = new OptionsObjectBuilder().name("asd").no(11).build();我只想将我需要的属性传递给new OptionsObject。就像现在这样--它可以工作,但我没有类型安全。我不想引入额外的interface,因为我需要复制属性。
有没有更好的方法来保证类型安全,或者有没有其他类似于构建器的模式来适应typescript?
发布于 2020-06-12 21:51:19
这可能是Typescript实用程序类型Partial<T>的一个很好的用例
来自documentation的示例
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: 'organize desk',
description: 'clear clutter',
};
const todo2 = updateTodo(todo1, {
description: 'throw out trash',
});发布于 2020-06-12 22:11:56
在本例中,您将告诉typescript构造函数接受class<OptionsObject>类型的对象。
OptionsObject不是一个普通的javascript对象,就像您试图传入的那样。
关于这一点:
我不想引入额外的接口,因为我需要复制属性。
你并不是在复制属性,你是在定义一个契约。如果您不熟悉composition设计模式,有几本书介绍了它,包括Head First design pattern和Clean Architecture,这两本书都可以在您选择的阅读平台上找到。
然而,回答你的问题的:
实现你想要的东西的唯一方法是使用一个接口。我在下面有一个例子,但从技术上讲,你不需要实现接口,你只需要把它用作参数的类型。通过实现接口,私有成员变量必须成为公共变量,因为和接口成员始终是公共的。
interface OptionsObject {
readonly name: string;
readonly no?: number;
}
class OptionsObjectImpl implements OptionsObject {
readonly name: string; // cannot be private due to being part of the interface
readonly no: number;
constructor(o : OptionsObject){
this.name = o.name;
this.no = o.no;
}
uradi() : void{
console.log(`Number is ${this.no} and name is ${this.name}`);
}
}
const p = new OptionsObjectImpl({
name:"asd",
no:11
}); //works with type-safety
p.uradi();希望这能有所帮助。
编辑:以无实现添加为例。
interface OptionsObjectInterface {
readonly name: string;
readonly no?: number;
}
class OptionsObject {
private readonly name: string; // cannot be private due to being part of the interface
private readonly no: number;
constructor(o : OptionsObjectInterface){
this.name = o.name;
this.no = o.no;
}
uradi() : void{
console.log(`Number is ${this.no} and name is ${this.name}`);
}
}
const p = new OptionsObject({
name:"asd",
no:11
}); //works with type-safety
p.uradi();发布于 2021-02-06 19:14:05
如果我们看一看Builder Pattern的概念,我们会看到该方法包含了几个简单的东西:
因此,TypeScript方法的所有不同之处在于,我们使用普通的javascript对象作为构建器对象,因为我们不需要像在Java语言中那样编写描述它的类。但是我们仍然需要类型安全,所以我们只定义构建器对象的一种类型。
此外,我们将把'build‘方法实现为主对象类的一个静态方法。
这是我们得到的结果:
class MyObject {
private constructor(readonly prop1: string, readonly prop2: number) {
}
// an alternative to the 'build' method
static createInstance(builder: MyObjectBuilder): MyObject {
// some validation...
return new MyObject(builder.prop1, builder.prop2);
}
}
// We make all props optional to allow specify
// them at any moment as if it would be a builder
type MyObjectBuilder = {
prop1?: string,
prop2?: number
};用法:
let builder: MyObjectBuilder = {};
builder.prop1 = 'text';
builder.prop2 = 7;
let myObject = MyObject.createInstance(builder);当然,在某些情况下,将builder直接传递给我们类的公共构造函数就足够了,但它不能完全替代Builder模式,因为它不仅提供了一种将选项传递给对象构造函数的方法,而且还让我们完全控制对象的构建(在高于对象本身的级别上)。
https://stackoverflow.com/questions/62345539
复制相似问题