打字稿提取物精确区分有条件工会在迭代法中类型
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进行过滤。
如何键入第三参数比较:任何
type filter_meta
stackblitz链接 的第一个参数 https://stackblitz.com/edit/depescript-ku6bq7
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))
)
);
The above is generic filter fn, which is trying to filter an array based on filter type.
Its provided with array of different filter, which uses the comparer fn to filter out.
How to type the 3rd argument comparer:any
from the 1st argument of type FILTER_META
Stackblitz Link
https://stackblitz.com/edit/typescript-ku6bq7
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
switch(theValue)中的值
必须与您嵌套到(iethevalue.filters.filters.id
)中的变量相同。Typescript将知道当前
theValue
的过滤器是“字符串”类型,而不是“时间”类型,仅仅是因为switch(thevalue.type)
。 没有它,(即您当前的代码)Typescript不知道id
是contrace>比较
中的关键,因为它不知道<<<代码>比较是类型“字符串”,“时间”或“范围”的类型。这就是为什么comparer.id
不是typescript-lim有效的原因,例如,如果
fo
是明确的:(注意:
.filters
是不是一个数组)然后这起作用:
The value in
switch(theValue)
must be the same variable as the one you're nesting into (i.etheValue.filters.id
).TypeScript will know that the current
theValue
's filters are of the "string" type and not the "time" type JUST because of theswitch(theValue.type)
. Without it, (i.e your current code) TypeScript can't know thatid
is a key incomparer
since it doesn't know whethercomparer
is of type "string", "time" or "range". That's whycomparer.id
is not TypeScript-ly validFor example, if
fo
is explicitly:(notice:
.filters
is not an array)then this works: