使用keyof进行参数通用推断

时间:2019-05-19 18:35:17

标签: typescript generics discriminated-union

我正在尝试使用功能参数来推断另一个功能参数的缩小通用类型的键。如果我用硬编码代替通用的类类型,那么一切似乎都可以正常工作。但是,当使用通用值时,第二个参数的范围缩小不起作用。现在已经呆了几天,我很茫然。

困惑吗?我知道我是...这是说明问题的代码。在最后一个函数中,第二个参数应解析为有效属性。

class A {
    readonly shortname = 'A';
    id: number;
    genStart: Date;
}

class B {
    readonly shortname = 'B';
    id: number;
    genPart: Date;
}


class C {
    readonly shortname = 'C';
    id: number;
    genEnd: Date;
}

type Entities = A | B | C;

type GetEtType<T extends Entities['shortname']>
    =  keyof Extract<Entities, { shortname: T }>;

class EtTester {
    tester<TShortName extends Entities['shortname'],
        TProp extends GetEtType<TShortName>>(shortName: TShortName,
        propName: TProp) {

    }
}

let et = new EtTester();

et.tester('B', 'genPart' )

任何帮助都会很棒。

Playground

1 个答案:

答案 0 :(得分:1)

如果我正确理解问题,GetEtType<T>应该返回由其通用类型参数T选择的实体类型的键,该参数必须是每个实体中定义的shortname值之一。 / p>

keyof Extract<...>不起作用,似乎keyof在解析为never时有时会急切地应用在条件类型评估中。

this answer之后,它说明了如何基于判别属性的类型选择已区分联合类型的成员,这是GetEtType的定义,在这里可以使用:

type GetEtType<T extends Entities['shortname']>
    = Entities extends (infer E)? 
        E extends Entities?
            E['shortname'] extends T ? keyof E : never : never : never
;