Typescript - 选项对象或生成器

问题描述 投票:0回答:1

所以,我试图在typescript中实现 "选项对象",我读到它是Java Builder模式的一个替代方案,我看到我可以使用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,因为这样我就需要重复属性。

有没有什么更好的方法来实现这个类型安全,或者有没有其他类似于 builder 的模式来适应 typescript?

typescript design-patterns builder
1个回答
0
投票

这可能是Typescript实用类型的一个很好的用例。Partial<T>

例子来自 文件

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',
});

0
投票

在你的例子中,你告诉typescript,构造函数接受一个类型为 class<OptionsObject>.

OptionsObject 并不是像你想传入的那个普通的javascript对象。

关于这个问题。

我不想引入额外的接口, 因为那样的话我需要重复的属性.

你不是真的重复属性,你是在定义一个合同。如果你不熟悉 composition 设计模式,有好几本书都有涉及,包括Head First Design Patterns和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();

希望能帮到你。

EDIT:补充一下没有实现的例子。

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();
© www.soinside.com 2019 - 2024. All rights reserved.