如何使用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