2016-08-10 20 views
0

使用以下代码;TypeScript鸭式打字:只需要一个属性

interface ParamTest extends Object { 
    ids?: any; 
    model?: any; 
    params?: any; 
    pageContext?: PageContext; 
} 

class Foo { 
    public callMeWithParamsPlease(params: ParamTest): void{ 

    } 

    public nope() { 
     this.callMeWithParamsPlease("hi"); 
    } 
} 

我不知道我将作为参数提供什么。但我知道至少有一个的字段必须填满。如果我使用:

export interface ApiServiceOpts extends Object { 
    ids?: any; 
    model?: any; 
    params?: any; 
    pageContext: PageContext; 
} 

然后,它不再与兼容的字符串,如预期 - 因为字符串没有pageContext。但是我不确定是否会提供pageContext - 但我知道至少需要提供一个字段。是否有任何神奇的打字稿语法允许这个?

也许类似于;

interface PageContext {} 


export interface ParamTestId { 
    ids: any; 
} 

export interface ParamTestModel { 
    model: any; 
} 

export interface ParamTestParams { 
    params: any; 
} 

export interface ParamTestPageContext { 
    pageContext: PageContext; 
} 

class Foo { 
    public callMeWithParamsPlease(params: ParamTestId & ParamTestModel & ParamTestParams & ParamTestPageContext): void { 
     params.ids.a = ""; 
     params.model.b = {} 
    } 

    public nope() { 
     this.callMeWithParamsPlease("hi") 
    } 
} 
+0

目前还不清楚你在问什么。 '“它不再与字符串兼容” - 它什么时候与一个字符串兼容,这个“它”是什么?没有你的代码中有一个字符串参数。另外,为什么要扩展Object? –

回答

0

我建议如下:

  • 扩展Object不添加任何东西,你的界面已经是一个对象。删除。
  • 你的类型是兼容string因为string也是一个Object但你不应该依赖于这个,而是使用型工会明确表示接受对象或字符串,即

    callMe(params:ParamTest|string) { 
        // params may be a string now regardless of ParamTest's definition. 
    } 
    
  • 在这点你应该使用类型卫士来检查你的PARAMS实际得到的,即:

    interface ParamTest { 
        ids:string[]; 
        paramContext:string; 
    } 
    class Foo { 
        callMeMaybe(params:ParamTest|string) { 
        if (params instanceof String) { 
         // Cool it's a string. 
         let x = params.charCodeAt(0); 
        } else { 
         let m = params.ids; 
        } 
        } 
    } 
    
+0

我不确定你是否理解这个问题; 'ParamTest'与'string'类型兼容。即使该函数明确接受了“ParamTest”,也可以将字符串传递给它,因为所有属性都是可选的。 – David