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,
    },
});

Playground link

(即使是现代浏览器的最新版本也使用了 relatively-new flat method. It's supported,但可能需要对旧版本进行 polyfilling。)