简体   繁体   中英

Override property in nested typescript interface

I have a typescript interface like so:

interface DataSku {
  fields: {
    sku: string;
  }
}

interface PostProduct {
  fields: {
    title: string;
    skus: DataSku[];
  }
}

Now I want to extend the Product interface so that each object in the skus array has an extra field. So I tried this:

interface Sku extends DataSku {
  stripe: Stripe.skus.ISku;
}

interface Product extends PostProduct {
  fields: PostProduct['fields'] & {
    skus: Sku[];
  }
}

In my code, I try a loop like so:

(product as Product).fields.skus.forEach(sku => console.log(sku.stripe));

This throws the following Typescript error:

Property 'stripe' does not exist on type 'DataSku'.

Have I extended the interface wrong? The console does output my stripe object as expected, so it's just Typescript that isn't happy with the definition.

A much more elegant (and working) approach for this would be to use generics .

Update PostProduct with a generic parameter that's used for the type of fields.skus :

interface PostProduct<T extends DataSku = DataSku> {
  fields: {
    title: string;
    skus: T[];
  }
}

T extends DataSku means the type has to be a subtype of DataSku . And we can even set a default value for T so PostProduct can also be used without having to specify the generic parameter.

Now, for Product we just have to pass Sku as generic parameter:

interface Product extends PostProduct<Sku> {}

Playground


That said, if you want to it without generics and without modifying DataSku and PostProduct . You could do this:

interface Product extends PostProduct {
  fields: Omit<PostProduct['fields'], 'skus'> & {
    skus: Sku[];
  }
}

Playground

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM