TypeScript - 我如何处理多个 IF
TypeScript - How can i deal with multiple IFs
我试图在 TS 中做一个“多重过滤器”,所以...
如果我什么都不发送 -> 它returns所有产品正常;
但是如果我发送一些 params -> 它 returns 由参数过滤的产品。
(我使用颜色只是为了示例)
async load(params: params): LoadProducts.Result => {
const products = [];
if (params) {
if (params.red != undefined) // products.push( ...load.redProducts() );
if (params.blue != undefined) // products.push( ...load.blueProducts() );
if (params.green != undefined) // products.push( ...load.greenProducts() );
if (params.yellow != undefined) // products.push( ...load.yellowProducts() );
} else {
// products.push( ...load.products() );
}
return products;
}
请求类型:
type params = {
filter?: {
red?: boolean;
blue?: boolean;
green?: boolean;
yellow?: boolean;
};
};
请求示例:
{
"filter": {
"red": true,
"blue": true
}
}
如何处理多个 IF 来验证参数,因为每个都有自己的函数要加载,我想添加更多过滤器。
您没有包含 minimal, reproducible example,但根据您 显示的内容,您可以使用 (map-like) 元组数组并迭代在上面:
const colorFns = [
['red', load.redProducts.bind(load)],
['blue', load.blueProducts.bind(load)],
// etc...
] as const;
async load(params: params): LoadProducts.Result => {
const products = [];
if (params) {
for (const [color, fn] of colorFns) {
if (params[color] != undefined) products.push(...fn());
}
} else {
// products.push( ...load.products() );
}
return products;
}
如果有很多个过滤器,首要的事情可能是避免重复自己。所以我会让执行加载的函数驱动过程:你用这些函数定义一个对象as const
,然后从中派生出你可能的过滤器。这是一个示例(请参阅内联注释):
// Placeholder for your product type
type Product = {
name: string;
type: string;
};
// The functions that do the loading of individual types
const loaders = {
async red() {
return [{ type: "red", name: "Red 1" }];
},
async blue() {
return [{ type: "blue", name: "Blue 1" }];
},
async green() {
return [{ type: "green", name: "Green 1" }];
},
async yellow() {
return [
{ type: "yellow", name: "Yellow 1" },
{ type: "yellow", name: "Yellow 2" },
];
},
} as const;
// A function that loads everything
const loadAll = async () => {
const allLoaders = Object.values(loaders);
return (
await Promise.all(allLoaders.map(loader => loader()))
).flat();
};
// The types of filters we might have
type FilterType = keyof typeof loaders;
// The params type
type ParamsFilters = {
[Key in FilterType]?: boolean;
};
type Params = {
filter?: ParamsFilters;
};
// A function that asserts a string key is a valid key for `loaders`
function assertIsLoaderKey(key: string): asserts key is keyof typeof loaders {
if (!(key in loaders)) {
throw new Error(`Expected key for 'loaders', got "${key}"`);
}
}
// The class this is apparently in
class Example {
async load(params: Params): Promise<Product[]> {
let products: Product[];
// If we have filters...
if (params.filter) {
// ...run them
products = (
await Promise.all(
Object.entries(params.filter)
.filter(([key, flag]) => flag)
.map(([key]) => {
assertIsLoaderKey(key);
return loaders[key]();
})
)
).flat();
} else {
// No filters, load everything
products = await loadAll();
}
return products;
}
}
// Example usage
const e = new Example();
e.load({
filter: {
red: true,
blue: true,
},
});
(即使是现代浏览器的最新版本也使用了 relatively-new flat
method. It's supported,但可能需要对旧版本进行 polyfilling。)
我试图在 TS 中做一个“多重过滤器”,所以...
如果我什么都不发送 -> 它returns所有产品正常;
但是如果我发送一些 params -> 它 returns 由参数过滤的产品。
(我使用颜色只是为了示例)
async load(params: params): LoadProducts.Result => {
const products = [];
if (params) {
if (params.red != undefined) // products.push( ...load.redProducts() );
if (params.blue != undefined) // products.push( ...load.blueProducts() );
if (params.green != undefined) // products.push( ...load.greenProducts() );
if (params.yellow != undefined) // products.push( ...load.yellowProducts() );
} else {
// products.push( ...load.products() );
}
return products;
}
请求类型:
type params = {
filter?: {
red?: boolean;
blue?: boolean;
green?: boolean;
yellow?: boolean;
};
};
请求示例:
{
"filter": {
"red": true,
"blue": true
}
}
如何处理多个 IF 来验证参数,因为每个都有自己的函数要加载,我想添加更多过滤器。
您没有包含 minimal, reproducible example,但根据您 显示的内容,您可以使用 (map-like) 元组数组并迭代在上面:
const colorFns = [
['red', load.redProducts.bind(load)],
['blue', load.blueProducts.bind(load)],
// etc...
] as const;
async load(params: params): LoadProducts.Result => {
const products = [];
if (params) {
for (const [color, fn] of colorFns) {
if (params[color] != undefined) products.push(...fn());
}
} else {
// products.push( ...load.products() );
}
return products;
}
如果有很多个过滤器,首要的事情可能是避免重复自己。所以我会让执行加载的函数驱动过程:你用这些函数定义一个对象as const
,然后从中派生出你可能的过滤器。这是一个示例(请参阅内联注释):
// Placeholder for your product type
type Product = {
name: string;
type: string;
};
// The functions that do the loading of individual types
const loaders = {
async red() {
return [{ type: "red", name: "Red 1" }];
},
async blue() {
return [{ type: "blue", name: "Blue 1" }];
},
async green() {
return [{ type: "green", name: "Green 1" }];
},
async yellow() {
return [
{ type: "yellow", name: "Yellow 1" },
{ type: "yellow", name: "Yellow 2" },
];
},
} as const;
// A function that loads everything
const loadAll = async () => {
const allLoaders = Object.values(loaders);
return (
await Promise.all(allLoaders.map(loader => loader()))
).flat();
};
// The types of filters we might have
type FilterType = keyof typeof loaders;
// The params type
type ParamsFilters = {
[Key in FilterType]?: boolean;
};
type Params = {
filter?: ParamsFilters;
};
// A function that asserts a string key is a valid key for `loaders`
function assertIsLoaderKey(key: string): asserts key is keyof typeof loaders {
if (!(key in loaders)) {
throw new Error(`Expected key for 'loaders', got "${key}"`);
}
}
// The class this is apparently in
class Example {
async load(params: Params): Promise<Product[]> {
let products: Product[];
// If we have filters...
if (params.filter) {
// ...run them
products = (
await Promise.all(
Object.entries(params.filter)
.filter(([key, flag]) => flag)
.map(([key]) => {
assertIsLoaderKey(key);
return loaders[key]();
})
)
).flat();
} else {
// No filters, load everything
products = await loadAll();
}
return products;
}
}
// Example usage
const e = new Example();
e.load({
filter: {
red: true,
blue: true,
},
});
(即使是现代浏览器的最新版本也使用了 relatively-new flat
method. It's supported,但可能需要对旧版本进行 polyfilling。)