如何使用magic TypeScript或递归?

如何使用magic TypeScript或递归?,typescript,typescript2.0,Typescript,Typescript2.0,我有两种方法: public prop<K extends keyof ResponseInvitation.RootObject>(key: K) { return this._has(key) ? this.user[key] : null; } private _has(prop: string): boolean { return this.user.hasOwnProperty(prop); } 当返回的属性为object时,调用this.p

我有两种方法:

public prop<K extends keyof ResponseInvitation.RootObject>(key: K) {
    return this._has(key) ? this.user[key] : null;
  }

  private _has(prop: string): boolean {
    return this.user.hasOwnProperty(prop);
  }
当返回的属性为object时,调用this.prop的链

 let prop = this.prop(this.prop('profile').organization);
注意:上面的意思是我试图通过名称
profile
获取属性。它以字符串的形式返回包含属性
组织的对象

我想我需要这个:

private _has(prop: string): boolean {
    let prop = this.user.hasOwnProperty(prop);

    if (typeof prop == 'object') {
       return this._has(prop);
    }
}
关于我的问题,我试图重写一个逻辑,得到了以下工作代码:

interface RootObject { 
  name: string;
  organization: Org; 
}

interface Org { 
  name: string;
}

class A { 

  public user: any;
  public last: string;

public prop<K extends keyof RootObject>(key: K) {
  let  prop = this._has(key) ? this.user[key] : null;

  if (key == this.last) { 
    return prop;
  }

  if (typeof prop == 'object') {
    let k = Object.keys(prop)[0] as K;
    this.user = prop;
    return this.prop(k);
  }

  }

  private _has(prop: string): boolean {
    return this.user.hasOwnProperty(prop);
  }

  public propString(properties: string) { 
    this.last = properties.split('.').slice(-1).pop();
  }

}

let b = {
  'organization': {
    'name': 'Oleg'
  }
};

let a = new A();
a.user = b;
a.propString('organization.name');
let d = a.prop('organization');
console.log(d);
接口根对象{
名称:字符串;
组织:组织;
}
接口组织{
名称:字符串;
}
A类{
公共用户:任何;
公共最后:字符串;
公共道具(钥匙:K){
让prop=this.\u有(key)?this.user[key]:null;
如果(key==this.last){
返回道具;
}
if(typeof prop==“object”){
设k=Object.keys(prop)[0]为k;
this.user=prop;
返回此。道具(k);
}
}
private\u has(prop:string):布尔值{
返回此.user.hasOwnProperty(prop);
}
公共propString(属性:string){
this.last=properties.split('.').slice(-1.pop();
}
}
设b={
“组织机构”:{
'name':'Oleg'
}
};
设a=新a();
a、 用户=b;
a、 propString('organization.name');
设d=a.prop(‘组织’);
控制台日志(d);

我不太确定您在寻找什么,因为您遗漏了大量的类实现。我将为您尝试实现的目标提供一个更通用的解决方案:

type WrapIfObject<T> = T extends object ? ObjectWrapper<T> : T; 
class ObjectWrapper<T> {
  constructor(public object: T) { }
  prop<K extends keyof T>(k: K): WrapIfObject<T[K]>;
  prop<K extends keyof T>(k: K): T[K] | ObjectWrapper<T[K]> {
    const val = this.object[k];
    return (typeof val === "object") ? new ObjectWrapper(val) : val;
  }
}
上述类型检查无错误;TypeScript知道
valWrap.prop(“a”).prop(“b”)
是一个
字符串,而
valWrap.prop(“c”)
是一个
字符串。如果你做错事,它会抱怨:

const oops = valWrap.prop("a").charAt(0); // error!
// Property 'charAt' does not exist on type 'ObjectWrapper<{ b: string; }>'.
const oops=valWrap.prop(“a”).charAt(0);//错误!
//类型“ObjectWrapper”上不存在属性“charAt”。
由于条件类型的属性,它将在正确的位置生成联合:

const x = new ObjectWrapper({a: Math.random() < 0.5 ? "string" : {b: 3}});
const y = x.prop("a") ; // string | ObjectWrapper<{b: number}>
const z = (typeof y === "string") ? y.length : y.prop("b"); // number
console.log(z); // 6 or 3
const x=newObjectWrapper({a:Math.random()<0.5?”字符串:{b:3});
常数y=x.prop(“a”);//字符串|对象包装器
常量z=(y的类型==“字符串”)?y、 长度:y.prop(“b”);//数
console.log(z);//6或3
请注意,
y
是如何被称为
字符串
对象包装器


无论如何,希望你能用它来给你一个如何解决你的问题的想法。祝你好运

你能看到我的更新吗?我试着建议一种方法。从我对代码的浏览中,我会说它看起来很脆弱,而且类型不正确。TypeScript不支持变异类型,因此,如果
a.prop(“组织”)
的结果类型取决于
a
的状态,那么您的日子就不好过了。我建议返回新对象,而不是像上面的
ObjectWrapper
那样修改现有对象。
const oops = valWrap.prop("a").charAt(0); // error!
// Property 'charAt' does not exist on type 'ObjectWrapper<{ b: string; }>'.
const x = new ObjectWrapper({a: Math.random() < 0.5 ? "string" : {b: 3}});
const y = x.prop("a") ; // string | ObjectWrapper<{b: number}>
const z = (typeof y === "string") ? y.length : y.prop("b"); // number
console.log(z); // 6 or 3