TypeScript duck typing:只需要一个属性

时间:2016-08-10 10:04:59

标签: typescript duck-typing

使用以下代码;

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")
    }
}

1 个答案:

答案 0 :(得分: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;
        }
      }
    }