约束作为查找类型

时间:2017-05-30 17:18:23

标签: typescript types algebraic-data-types complex-data-types

我需要创建一个约束,将TP1关键字列出的keyof键限制为特定类型的属性。当我使用builder.setMetadata方法时,第一个参数不应接受字符串“configure”作为有效值(它应该接受foo和其他键入为Foo<something>的键)。我试图自己想出一个解决方案,但是我有点迷失了,现在已经做了三个多小时了。以下是工作代码:

interface Foo<T> {};

class Test { prop: string; }

class Builder<T> {
    public setMetadata<TP1 extends keyof this, TP2 extends keyof this[TP1]>(prop: TP1, propOfProp: TP2) {
        // ...
    }
}

class Bar {
    foo: Foo<Test>;

    configure(builder: Builder<Bar>) {
        builder.setMetadata("", ""); // only "foo" should be accepted value in the first argument, "configure" shouldn't be in the list
    }
}

2 个答案:

答案 0 :(得分:0)

这个怎么样?

class Builder<T> {
  public setMetadata<TP1 extends keyof T, TP2 extends T[TP1]>(prop: TP1, propOfProp: TP2) {
    // ...
  }
}

class BarData {
  foo: Foo<Test>;
}

class Bar extends BarData {
  configure(builder: Builder<BarData>) {
    // ...
  }
}

我在几个地方做了改变:

  • 在setMetadata的类型中使用T代替this
  • 请勿在setMetadata的第二个参数类型中使用keyof
  • 将foo移到单独的班级

答案 1 :(得分:0)

我自己使用函数解决了这个问题:

function createInstance<T extends Function & { [P in keyof TSchema]: Foo<any> }>(schema: T, configure: (builder: Builder<T["prototype"]>) => void): any {
    // ...
}