Reputation: 13270
I want to make an interface that represents my application data, basically my initial data object is :
const data = {
wallet: { ... },
orders: [{ ... }, { ... }, ...],
}
wallet
and orders
are initial properties.
Now the data object can have volatile properties that represents cryptocurrency objects.
For instance the data object can be of this form :
const data = {
wallet: { ... },
orders: [{ ... }, { ... }, ...],
btc: { ... },
eth: { ... },
...
}
Here's my typescript definition :
export interface Data {
wallet?: any
orders?: Order[]
[cryptoname:string]: CryptoObject
}
but typescript returns this exception :
Property 'orders' of type 'Order[] | undefined' is not assignable to string index type 'CryptoObject'.ts(2411)
What am I doing wrong ?
EDIT: I understand why I get this exception now. Typescript expects all the properties to be a CryptoObject
.
My question is still opened because I wonder how to write the definition for this type of data structure.
Upvotes: 0
Views: 198
Reputation: 13270
Thanks to @Kyll answer. What I needed was intersection type
export type Data = {
wallet?: any,
orders?: Order[]
} & {[cryptoname:string]:CryptoObject}
Upvotes: 1
Reputation: 7139
I would use an intersection type:
type Cryptos = 'btc' | 'eth'
type Data = {
wallet?: any
} & Record<Cryptos, any>
const myData: Data = {
wallet: 'foobar',
btc: 123,
eth: 456
}
See playground. You can fiddle around with the exact definition of your intersection to get the best results. If you want to make your Cryptos
optional, use Partial<Record<Cryptos>>
.
also don't use any please
Upvotes: 1
Reputation:
[cryptoname: string]
is an index signature, which makes it so that:
As soon as you have a string index signature, all explicit members must also conform to that index signature.
So by using an index signature here, you're saying that all members of your Data
interface need to be CryptoObject
s. Which is obviously incompatible with Order[] | undefined
.
I don't really have an answer how to solve it for you except for adding individual members for each crypto you want to support. Like:
export interface Data {
wallet?: any
orders?: Order[]
btc?: CryptoObject
eth?: CryptoObject
}
Upvotes: 2