Home > OS >  How to provide a nested Generic in typescript?
How to provide a nested Generic in typescript?

Time:06-24

I'm using state library zustand with typescript. I want to store an object that has at least an id:number. Now I get an error, because the nested Generic is not defined correctly. How can I fix that?

Cannot find name 'T'.ts(2304)

Code

type HasId = { id: number }

export type Product<T extends HasId> = {
  product: T | null
  setProduct: (product: T | null) => void
}

export const useProductStore = create<Product<T>>(set => ({
  product: {id: 2, color: "red", // other unknown props},
  setProduct: product => {
    set({ product })
  },
}))

CodePudding user response:

Explanation for Cannot find name 'T'.ts(2304)

Pretty simply the reason why the compiler is throwing that error, is because there is no variable named T within your code, at least in the snippet provided

export type Product<T extends HasId> = {
  product: T | null
  setProduct: (product: T | null) => void
}

Type Product takes an argument T which is basically of the same type as HasId

"Translated"

export type Product<T extends HasId> = {
   product: object with prop id and number value ({id:4}) | null
   setProduct: (product: object with prop id and number value ({id:4}) | null) => void
}

In order for the compiler to stop complaining on your scenario you would need to pass a valid argument to your type, for example:

export const useProductStore = create<Product<{id: 2}>>(set => ({
  product: {id: 2, color: "red", // other unknown props},
  setProduct: product => {
    set({ product })
  },
}))

Since {id: 2} conforms to your generic T, the compiler is now happy.

For your specific scenario I think the best approach would be to ditch the generic and have a type like so:

export type Product = {
    product: HasId | null
    setProduct: (product: HasId | null) => void
}

and your function becomes

export const useProductStore = create<Product>(set => ({
  product: {id: 2, color: "red", // other unknown props},
  setProduct: product => {
    set({ product })
  },
}))
  • Related