使用泛型编写帮助程序以使用TypeORM中的共享库保存实体

时间:2020-07-02 04:10:26

标签: typescript typeorm

我正在尝试编写一个帮助程序来保存共享基本实体的产品,并且在将泛型用于.find方法的返回值时遇到了麻烦。

我遇到的麻烦是在saveProduct中,我将实体作为通用对象传入addProducts> addProduct> saveProduct中。返回的existingProduct的类型为T,但是我无法访问其上的任何属性,即existingProduct.id抛出错误而不将其强制转换为任何错误。我该怎么写才能删除as any

type DbEntity<T> = string | Function | EntitySchema<T> | (new () => T);

const saveProduct = async <T>(
  productType: keyof TargetStoreCategories[0],
  product: Item,
  productEntity: DbEntity<T>,
  storeLocation: StoreLocation
): Promise<T> => {
  try {
    const repo: Repository<T> = getRepository(productEntity);
    const brand = await addBrand(product);

    // #region I need help with

    // The Entity `BaseProduct` has a `name` and other shared fields.
    const existingProduct = await repo.findOne({
      name: product.name,
      brand,
    } as FindOneOptions<T>);

    if (existingProduct) {
      const e = existingProduct as any;
      const productWithLocations = (await repo.findOne(e.id, {
        relations: ["locations"],
      })) as any;

      // is there a better way to check if an existing relation exists already? 
      const locationIndex = productWithLocations?.locations.findIndex(
        (location: StoreLocation) => location.id === storeLocation.id
      );
      if (locationIndex !== -1) {
        productWithLocations.locations.push(storeLocation);
        await repo.save(productWithLocations);
      }

      return existingProduct;
    }
    
    // #endregion

    const createdProduct = await createProduct(
      productType,
      product,
      brand,
      storeLocation
    );
    const productToBeSaved = repo.create(
      createdProduct as DeepPartial<typeof Entity>
    );
    const savedProduct = await repo.save(productToBeSaved);

    return savedProduct;
  } catch (e) {
    winston.error(e.message);
  }
};

const addProduct = async <T>(
  productType: keyof TargetStoreCategories[0],
  entity: DbEntity<T>,
  targetStoreCategories: TargetStoreCategories,
  storeLocation: StoreLocation
) => {
  const products = targetStoreCategories[productType].products;

  for (const product of products) {
    await saveProduct<T>(productType, product, entity, storeLocation);
  }
};

export const addProducts = async (
  targetStoreCategories: TargetStoreCategories,
  storeLocation: StoreLocation
) => {
  await addProduct<Shirt>(
    ProductTypes.Shirt,
    Shirt,
    targetStoreCategories,
    storeLocation
  );
  await addProduct<Pants>(
    ProductTypes.Pants,
    Pants,
    targetStoreCategories,
    storeLocation
  );
  await addProduct<Shoes>(
    ProductTypes.Shoes,
    Shoes,
    targetStoreCategories,
    storeLocation
  );
};

谢谢!

0 个答案:

没有答案