Home > front end >  typescript - can't access added returned variable
typescript - can't access added returned variable

Time:10-24

The SQL query -

  const currency = req.query.currency; - the query options: "BTCUSD" | "ETHUSD" | "LTCUSD"

    const allPrices = await Crypto.findAll({ attributes: [currency, 'createdAt'], order: [['createdAt', 'ASC']], raw: true });

The Crypto -

class Crypto extends Sequelize.Model<IDBCryptoAttributes> implements IDBCryptoAttributes {
  public id!: number;
  public BTCUSD!: number;
  public ETHUSD!: number;
  public LTCUSD!: number;
  public readonly createdAt!: Date;
}

allPrices objects for example -

  {
    BTCUSD: '4526.341078145248',
    createdAt: 2021-10-22T20:51:23.000Z,
  },
  {
    BTCUSD: '4600.428393851253',
    createdAt: 2021-10-22T20:52:24.000Z,
  },

Adding the first variable value from allPrices to the array before sending it to client -

const toClient = allPrices.map((item, index) => {
      if (index === 0) {
        return item;
      }

      return {
        ...item,
        price:  item[currency]    allPrices[0][currency],
      }
    });

toClient objects for example -

{
    BTCUSD: '4526.341078145248',
    createdAt: 2021-10-22T20:51:23.000Z,
    price: 69989.82615963052
  },
  {
    BTCUSD: '4600.428393851253',
    createdAt: 2021-10-22T20:52:24.000Z,
    price: 70063.91347533654
  },

So I want to send it like this to the client -

res.status(200).send({
      success: true,
      message: "Successfully retrieved Historic prices",
      data: toClient.map((price) => ({
        price: price.price,
        createdAt: price.createdAt,
      })),
    });

The problem is -

Property 'price' does not exist on type 'Crypto | { price: number; id: number; BTCUSD: number; ETHUSD: number; LTCUSD: number; createdAt: Date; _attributes: IDBCryptoAttributes; _creationAttributes: IDBCryptoAttributes; isNewRecord: boolean; sequelize: Sequelize; _model: Model<...>; }'.
  Property 'price' does not exist on type 'Crypto'.ts(2339)

CodePudding user response:

As the error states, the type Crypto doesn't contain the property price, so a type Crypto | AnyOtherType doesn't contain this property all the time.

In other words, in order to reference a property from a union type, it needs to be common between all the components of this type.

Specifically, the issue is in the following snippet, where you apply the change to all elements except the first, which results in a union type. Maybe you can explain why the special treatment to the first element.

   const toClient = allPrices.map((item, index) => {
      if (index === 0) {
        return item;
      }

      return {
        ...item,
        price:  item[currency]    allPrices[0][currency],
      }
    });

However, if you'll accept undefined or null instead of the price for the first element, then you can do the following, to check whether the object contains the price property.

const data = toClient.map((price) => ({
    price: "price" in price ? price.price : undefined,
    createdAt: price.createdAt,
}))
  • Related