Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 类型脚本:联合构造函数类型_Typescript - Fatal编程技术网

Typescript 类型脚本:联合构造函数类型

Typescript 类型脚本:联合构造函数类型,typescript,Typescript,我正在尝试在typescript中创建一个小的不可变类: import * as _ from "lodash"; export class Immutable<T> { constructor(public data:T) { Object.freeze(data); _.each(_.keysIn(data), (key) => { Object.defineProperty(this, key, <PropertyDescrip

我正在尝试在typescript中创建一个小的不可变类:

import * as _ from "lodash";

export class Immutable<T> {

  constructor(public data:T) {
    Object.freeze(data);

    _.each(_.keysIn(data), (key) => {
      Object.defineProperty(this, key, <PropertyDescriptor> {get: () => this.data[key]})
    })
  }

  set(key:string, val:any):Immutable<T> {
    if (_.isEqual(this.data[key], val)) {
      return this;
    }

    let newData = {};
    newData[key] = val;
    return new Immutable<T>(_.defaults<T>(newData, this.data))
  }

  update(data:T) {
    let newVal = _.defaults<T>(data, this.data);

    return _.isEqual(this.data, newVal) ? this : new Immutable<T>(newVal);
  }

  get(key):any {
    return this.data[key];
  }

  toJson():T {
    return this.data;
  }
}
这使得s。这样可能:

class Child extends Immutable<{x:number}> {
  constructor(data = {x: 1}) {
    super(data)
  }
}
类子级扩展不可变{
构造函数(数据={x:1}){
超级(数据)
}
}

不过,我还是不想回答这个问题,因为我仍然想知道如何让Typescript知道导出的类具有比定义的更多的属性(可能是像我一样通过外部添加的或构造函数添加的)

因为您发现类型系统不允许您说类本身不为类扩展。你可能会用一个
函数来破解一些东西。但是请不要。例如,如果属性
update
存在于
T
上,它将与您的
不可变冲突。update

您无法定义构造函数的返回类型,但是,您可以使用静态工厂方法来实现您需要的:

导出类不可变{
//您可以保护您的构造函数。
受保护构造函数(公共数据:T){
冻结(数据);
_.each(u.keysIn(数据),(键)=>{
Object.defineProperty(this,key,{get:()=>this.data[key]})
})
}
静态创建(数据:T):不可变&T{
返回新的(不可变的)(数据);
}
//TypeScript 2.1中另一个非常有用的新特性:keyof,请参阅下面的用法。
get(key:K):T[K]{
返回此.data[键];
}
// ...
}
//用法:
var obj=Immutable.create({x:1});
控制台日志(obj.x);
console.log(obj.get(“x”));
//TypeScript将生成编译错误:
//类型为“”的参数不能分配给类型为“”x“”的参数。

console.log(obj.get(“y”))新的子对象({x:3})。x
?Jep,这个测试在我做的地方工作:这个测试是针对运行时行为的,它没有说明太多关于类型脚本的键入。我想你也需要正确的键入?嗯,不过typescript会编译它。但是你的权利,在另一个类上,我必须手动声明属性而不设置它们,以便typescript知道它们的存在。是的,typescript的主要重点是提供设计时键入,但这并不阻止你做typescript不理解但编译良好的工作代码的事情。
class Child extends Immutable<{x:number}> {
  constructor(data = {x: 1}) {
    super(data)
  }
}