繁体   English   中英

从通用参数类型确定 typescript 属性联合

[英]Determine typescript property union from generic argument type

我有一些过滤操作

type FilterOp = 'Equals' | 'NotEquals' | 'Greater' | 'GreaterEqual' | 'Less' | 'LessEqual';
type ArrayFilterOp = 'In' | 'NotIn';
type StringFilterOp = 'StartsWith' | 'EndsWith' | 'Contains' | 'NotContains';
type DateFilterOp = 'DateIn' | 'DateNotIn'

这是我当前的过滤器定义

type GenericFilter<T> = {
    Property: string,
    Value: T,
    Operation: FilterOp | ArrayFilterOp | StringFilterOp | DateFilterOp
}

是否可以根据T参数以某种方式确定Operation类型? 例如,如果我的TDate那么 typescript 将只允许将DateFilterOpFilterOp分配给Operation属性

let dateFilter: GenericFilter<Date> = {
    Property: "DateCreated",
    Value: new Date(),
    Operation: // now I can only set value from FilterOp or DateFilterOp
}

假设我正确理解了约束,您可以使用条件类型来表示它:

type Operation<T> =
  | FilterOp
  | (T extends Array<any> ? ArrayFilterOp : never)
  | (T extends string ? StringFilterOp : never)
  | (T extends Date ? DateFilterOp : never);

type GenericFilter<T> = {
  Property: string;
  Value: T;
  Operation: Operation<T>;
};

这将支持您声明的用例:

let dateFilter: GenericFilter<Date> = {
  Property: "DateCreated",
  Value: new Date(),
  Operation: "DateIn"
};

以及与帮助器 function 一起工作,这样您就可以推断T而不是手动指定它:

const asGenericFilter = <T>(filt: GenericFilter<T>) => filt;

let stringFilter = asGenericFilter({
  Property: "Name",
  Value: "Alice",
  Operation: "StartsWith" // hinted as Operation<string>
})

希望有帮助; 祝你好运!

链接到代码

我已经设法通过OperationMap实施解决方案

type OperationMap<T> = 
    T extends Date
        ? (DateFilterOp | FilterOp)
        : T extends Array<any>
            ? ArrayFilterOp
            : T extends String
                ? FilterOp | StringFilterOp
    : FilterOp;

type GenericFilter<T> = {
    Property: string,
    Value: T,
    Operation: OperationMap<T>
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM