I want to use a property within a Typescript Interface's instance to compute a second property. I've been looking into Generics but I'm not successfully implementing this yet. :
Here's an example
// Here I define all valid names - works fine!
type ModalNames = 'payment' | 'source'
// This interface implements all expected payloads
// for each name
interface ModalPayloads {
payment: {
plan: string
}
source: {
metadataId: string
}
}
// How do I use the instance name
// to grab the correct payload property?
export interface ShowModalPayload {
name: ModalNames
modalProps?: ModalPayloads[instance.name]
}
In other words, for a given instance
of ShowModalPayload
, I want to assign modalProps
to a type derived from instance.name
. Hopefully this makes sense!
I'd use generics for this:
export interface ShowModalPayload<K extends ModalNames> {
name: K
modalProps?: ModalPayloads[K]
}
Note the use of ModalPayloads[K]
in place of ModalPayloads[instance.name]
. That's called a lookup type and it allows you to describe the type of m[k]
where m
has type ModalPayloads
and k
has type K
.
Anyway the ShowModalPayload
interface is now generic in K
, which should be one of the ModalNames
literals:
declare const smpPayment: ShowModalPayload<'payment'>;
smpPayment.name // "payment"
smpPayment.modalProps // {plan: string} | undefined
declare const smpSource: ShowModalPayload<'source'>;
smpSource.name // "source"
smpSource.modalProps // {metadataId: string} | undefined
Those correspond to what you're looking for, I think. Note that the following is still possible:
declare const smpWhoKnows: ShowModalPayload<ModalNames>
smpWhoKnows.name // ModalNames
smpWhoKnows.modalProps // {plan: string} | {metadataId: string} | undefined
which is possibly not what you want, but is not prohibited. The above definition is probably sufficient for most use cases, though.
Hope that helps. Good luck!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.