Reputation: 994
I need to extend a generic list of Array which has been extended from my class. How to do it properly?
export interface DeliveryMethod {
readonly id: string;
readonly company: string;
readonly cost: number;
readonly threshold: number;
readonly intervals: Array<Interval>;
readonly paymentMethods: Array<PaymentMethod>;
}
export interface Delivery {
selected: SelectedDelivery;
available: { [key : string] : Array<T extends DeliveryMethod>};
}
Cannot find name 'T'.ts(2304)
available: { [key : string] : Array<T extends DeliveryMethod>};
For example i need something like that:
const Delivery = {
selected :{/*data inside*/},
available:{
pickup: [<Pickup>{},<Pickup>{}],
courier: [<Courier>{},<Courier>{}]
}
}
Upvotes: 5
Views: 6237
Reputation: 10374
The @aopanasenko answer is fine. I want to complete it adding a way to solve the problem of multiple specifications.
If the properties of available
aren't much, and they're fixed and stable, then you could think about listing them all in the Delivery
interface:
interface Delivery<T extends DeliveryMethod, U extends DeliveryMethod> {
available: { [key : string] : Array<T | U>};
};
Then you can define the delivery
object like this:
const delivery: Delivery<Pickup, Courier>
If you don't know the properties a priori, then you need a way to link a property name to a TypeScript type, for example I added an available
object just for the mapping:
interface Delivery {
available: { [key: string]: Array<DeliveryMethod> | null };
};
const delivery: Delivery = {
available: {}
}
const available: {
pickup: Pickup[] | null,
courier: Courier[] | null
} = {
pickup: null,
courier: null
};
delivery.available = { ...delivery.available, ...available };
In this way, it's correctly type-checked. I also added | null
in order to provide an example, you can remove it.
Upvotes: 3
Reputation: 478
Update
As mentioned by @AndreaSimoneCosta in comment the following code should work:
export interface DeliveryMethod {
readonly id: string;
readonly company: string;
readonly cost: number;
readonly threshold: number;
readonly intervals: Array<Interval>;
readonly paymentMethods: Array<PaymentMethod>;
};
export interface Delivery<T extends DeliveryMethod = DeliveryMethod> {
selected: SelectedDelivery;
available: {
[key : string] : Array<T>
};
};
You should define generic type parameter list in angle brackets following the name of the Delivery
interface:
export interface DeliveryMethod {
readonly id: string;
readonly company: string;
readonly cost: number;
readonly threshold: number;
readonly intervals: Array<Interval>;
readonly paymentMethods: Array<PaymentMethod>;
};
export interface Delivery<T extends DeliveryMethod> {
selected: SelectedDelivery;
available: {
[key : string] : Array<T>
};
};
Upvotes: 0