Typescript在迭代器方法中提取精确的判别条件联合类型


export type FILTER_META =
| {
type: 'string';
key: string;
filters: { id: string; label?: string }[];
}
| {
type: 'time';
key: string;
filters: { min: string; max: string  }[];
}
| {
type: 'range';
key: string;
filters: { min: number; max: number }[];
};
type Unpacked<T> = T extends (infer U)[] ? U : T;
type Foo = Unpacked<FILTER_META['filters']>;
// how to determine comparer type from meta object
// comparer:Foo doesn't work
// const comparator = <T extends FILTER_META, U extends Unpacked<T['filters']>>(
const comparator = (meta: FILTER_META, item: any, comparer: any) => {
const DATE_PREFIX = '1/1/2022 ';
switch (meta.type) {
case 'string':
return item?.[meta.key]?.toLowerCase() === comparer.id?.toLowerCase();
case 'time': {
const { min, max } = comparer;
const compTime = new Date(DATE_PREFIX + item?.[meta.key]);
return (
new Date(DATE_PREFIX + min) <= compTime &&
compTime <= new Date(DATE_PREFIX + max)
);
}
case 'range': {
const { min, max } = comparer;
const compItem = item?.[meta.key];
return min <= compItem && compItem <= max;
}
}
};

const genericFilter =
(filterMeta: FILTER_META[]) =>
(list = []) =>
list.filter((item) =>
filterMeta
.filter((fMeta) => fMeta.filters.length)
.every((meta) =>
meta.filters.some((ft: any) => comparator(meta, item, ft))
)
);

上面是通用过滤器fn,它试图根据过滤器类型过滤数组。它提供了一个不同过滤器的数组,它使用比较器fn来过滤。

如何从类型为FILTER_META的第一个参数中输入第三个参数comparer:any

Stackblitz链接https://stackblitz.com/edit/typescript-ku6bq7

switch(theValue)中的值必须是相同的变量作为你正在嵌套的(即theValue.filters.id)。TypeScript会知道当前theValue的过滤器是"string"键入而不是"时间"。因为switch(theValue.type),(即你当前的代码)TypeScript不能知道idcomparer中的一个键,因为它不知道comparer的类型是否为"string", "time"或";range"。这就是为什么comparer.id不是typescript有效的

例如,如果fo显式为:(注意:.filters而不是)一个数组)

type fo =  {
type: 'string';
key: string;
filters: { id: string; label?: string }; // not an array (is unpacked")
}
| {
type: 'time';
key: string;
filters: { min: string; max: string }; // not an array (is "unpacked")
}
| {
type: 'range';
key: string;
filters: { min: number; max: number }; // not an array (is "unpacked")
};

const comparator = (meta: FILTER_META, item: any, comparer: fo) => {
const DATE_PREFIX = '1/1/2022 ';
switch (comparer.type) {
case 'string':
return item?.[meta.key]?.toLowerCase() === comparer.filters.id?.toLowerCase();
case 'time': {
const { min, max } = comparer.filters;
const compTime = new Date(DATE_PREFIX + item?.[meta.key]);
return (
new Date(DATE_PREFIX + min) <= compTime &&
compTime <= new Date(DATE_PREFIX + max)
);
}
case 'range': {
const { min, max } = comparer.filters;
const compItem = item?.[meta.key];
return min <= compItem && compItem <= max;
}
}
};

相关内容

  • 没有找到相关文章

最新更新