我有两种方法:
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);
}
我这样使用:
let prop = this.prop('profile'); // Return object
在返回的属性为对象的情况下,热调用this.prop
的链:
let prop = this.prop(this.prop('profile').organization);
上面的注释表示我试图通过名称profile
获取属性。它返回其中具有属性organization
作为字符串的对象。
我认为我需要这个:
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);
答案 0 :(得分:3)
由于您遗漏了许多类实现,因此我不确定您要查找的内容。我将为您要实现的目标提供更一般的解决方案:
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;
}
}
上面是一个名为ObjectWrapper
的类,该类包装了您在构造函数中传递的对象。当您使用对象的键之一调用prop()
方法时,如果返回值不是对象,则返回值将是属性值,或者将{适当的价值。通过这种方式,您可以将调用链接到ObjectWrapper
,直到获得非对象值为止。请注意,prop()
,prop()
的返回类型是conditional type而不是并集,这使编译器能够以更易于使用的方式强烈键入输出。>
让我们看看它是如何工作的:
WrapIfObject<T[K]>
上面的类型检查没有错误; TypeScript知道const val = {a: {b: "hey"}, c: "you"};
const valWrap = new ObjectWrapper(val);
console.log(valWrap.prop("a").prop("b").charAt(0)); // "h"
console.log(valWrap.prop("c").charAt(0)); // "y"
是valWrap.prop("a").prop("b")
,而string
是valWrap.prop("c")
。如果您做错了事,它将抱怨:
string
由于条件类型的distributive属性,它将在正确的位置产生并集:
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
是 一个y
还是一个string
。
无论如何,希望您可以使用它来给您一个解决问题的想法。祝你好运!