所以,我试图在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实用类型的一个很好的用例。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',
});
在你的例子中,你告诉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();