0

I've just found out I can do:

interface Product {
  name: string,
  price: number,
  category: string,
  id: string,
  quantity: number
}

bagTotal = (products: Product[]) => {

}

which is useful but I have this. where bag is one of my props coming from my redux store

interface IBagProps {
  bag: {
    products: Product[]
  }
}

so in the parameters of the function I want to use the bag props from the IBagProps interface

how do I this?

I wanted to do something like this: bagTotal = (products: IBagProps) => {

but that looks like it's going to pass all the props through

5
  • bagTotal = (products: Product[]) ...? Commented Dec 29, 2018 at 18:55
  • @quirimmo what's the question sorry? Commented Dec 29, 2018 at 19:06
  • Why the function param cannot be a simple array of Product? Commented Dec 29, 2018 at 19:19
  • because products is an array in the bag object and bag comes from props. so I thought that it should have to live in the props interface? Commented Dec 29, 2018 at 19:31
  • @quirimmo does that make sense? Commented Dec 29, 2018 at 19:47

3 Answers 3

1

You can access to the type of the bag member simply like this:

type BagsInfo = IBagProps['bag']

You can then refactor the bagTotal function to something similar to:

function bagTotal(bagsInfo: BagsInfo) {
  return bagsInfo.products.length
}

If your bagTotal function is directly "connected" to the products array you can retrieve the Product type with:

type Product = IBagProps['bags']['products'][number]
Sign up to request clarification or add additional context in comments.

2 Comments

ok, I missed the point. I need more context info: how are you connecting bagTotal to IBagProps? Is it a redux selector? as a solution you can adapt the input argument: const adapt = (fn: (products: Product[]) => number) => (bagProps: IBagProps) => fn(bagProps.bag.products) and then when using bagTotal just wrap with adapt(bagTotal)
ok I'll try and explain better. I know I can do this: bagTotal = (products: Product[]). but I just wanted to get it from IBagProps because I thought it makes more sense to put it in the props seeing as it's from there?
1

It's as simple as this:

const bagTotal = (products: IBagProps['bag']['products']) => {

}

But normally you just directly use Product[].

UPD, if you probably mean that IBagProps is passed to your function and you have to pull products from there, then destructuring like this can be done:

const bagTotal = ({ bag: {products} }: IBagProps) => {
    products.map(p => p.name)
  }

2 Comments

that first way doesn't look correct though and I've not seen people use it like that. I understand I can just use Product[] but does that mean in my PropsInterface for this class that I should leave bag empty?
@RedBaron There is not much wrong with the first approach, however, as I said, normally you just use Product[]. Regarding your second question I didn't get it, sorry. I am not too familiar with react, hence with PropsInterface as well.
1

You could leverage lookup types:

class Bag extends React.Component<IBagProps> {
  bagTotal = (products: IBagProps['bag']['products']) => {
    /* ... */
  }
}

but it is hardly the most elegant approach. If your method depends on Product[], it is perfectly fine to say:

class Bag extends React.Component<IBagProps> {
  bagTotal = (products: Product[]) => {
    /* ... */
  }
} 

Not only is it more readable, but it also doesn't depend on the shape of your props. If one day you decide to change their structure to, let's say:

interface IBagProps {
  products: Product[]
}

your method signature will not be affected — as it shouldn't be.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.