2
我想使用一成不变的类,而不是不可变的界面,有两个原因:Typescript - 如何操作不可变类?
- 这样我可以捆绑一些代码与它们(如
doStuff
方法) - 不允许“外来属性”(见实施例下面:在任何地方它是有效的设置
otherThing
,我想这引起编译错误)
这是最接近我已经能够拿出这主要是做什么,我想:
interface IData4 {
readonly thing1: string;
readonly thing2: string;
}
class Data4 implements IData4 {
readonly thing1: string;
readonly thing2: string;
constructor(that: IData4, props?: Partial<IData4>){
Object.assign(this, that);
if(props){
Object.assign(this, props);
}
}
doStuff(){
return this.thing1 == this.thing2;
}
}
// more verbose than a normal ctor parameter list, but I like it better anyway
// more readable, and it makes transposition errors less likely when all
// the params are the same type
// I write code to create instances rarely, reading and updating is more frequent
let data4 = new Data4({thing1: "t1", thing2: "t2"});
// GOOD!: error because of "otherThing"
// let other = new Data4({thing1: "t1", thing2: "t2", otherThing: 'blah'});
// GOOD!: error because missing "thing2"
// let other = new Data4({thing1: "t1"});
// this is the usual update case
let data4a = new Data4(data4, {thing2: "t2a"});
log.debug("data4a: " + JSON.stringify(data4a));
// GOOD! error because of "otherThing"
// let other = new Data4(data4, {thing2: "t2b", otherThing: 'blah'});
// BAD! want "otherThing" to cause error
// but I'm unlikely to use this construct, I wouldn't specify the spread
// operator again because I already specified the thing to copy from
let bad2b = new Data4(data4, {...data4, thing2: "t2b", otherThing: 'blah'});
// BAD! want "otherThing" to cause error
// easy to do accidentally because I'm used to using interfaces
let bad2c = new Data4({...data4, thing2: "t2b", otherThing: 'blah'});
let iData: IData4 = {thing1: 't1', thing2: 't2'};
// BAD! want an error about "otherThing"
let iData2 = {...iData, thing2: 't2a', otherThing: 'blah'};
// GOOD! error because of "otherThing"
// let other: IData4 = {thing1: 't1', thing2: 't2', otherThing: 'blah'};
// GOOD! error because lack of "thing2"
// let other: IData4 = {thing1: 't1'};
个
问题与这个结构:
- 全接口+级结构是笨拙和复制的属性定义是愚蠢的(加上容易出错)
- 它仍然允许我,如果我使用指定无关性“传播”运营商
那么,有没有更好的方法来做到这一点?
- 是否有某种方法来打包函数与我想要的接口?
- 或者是否有比我应该使用的“部分”更好的类型?
- 是否有某种方法可以实现与Partial大致相同的功能,但不允许设置无关属性?
- 或者在Typescript中有一些方法,我可以使用带参数列表的普通构造函数来创建具有更改属性的新对象,但不必指定每个属性?
- 具体来说,我不想做:
let data4a = new Data4(data4.thing1, "t2a"});
- 具体来说,我不想做:
大多数重视不变性的函数式语言都有一个构造,它创建一个对象的新副本,并改变某些字段,例如[F#'s'with'](https://docs.microsoft.com/en-us/docs.microsoft。COM/EN-US/DOTNET /用品/ fsharp /语言参考/复制和更新记录表达式)。 JS/TS不是强调不变性的函数式语言。你可以用'WithX(x:X)'方法来模拟它,但是如果你的对象有很多属性,那就很乏味了。一些项目([例如C#编译器](https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Syntax/Syntax.xml))使用代码生成器 –