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