TS2315错误:泛型类型ShopifyCollectionProduct为何提示非泛型?
问题根源分析
1. 第一个代码的遮蔽问题
你在ShopifyCollection接口里定义的第一个泛型参数名为ShopifyCollectionProduct,这直接遮蔽了外部同名的泛型类型别名。在接口内部,ShopifyCollectionProduct不再是你定义的带泛型参数的类型,而是一个普通的无泛型约束的类型参数——自然无法用<IsInformed>去调用它,因此触发TS2315错误。
2. 第二个代码的类型理解错误
改写后的代码中,ProductType extends ShopifyCollectionProduct存在核心误解:ShopifyCollectionProduct是泛型类型别名,当你不带泛型参数使用它时,TypeScript会自动应用其默认泛型参数(即'uninformed'),最终ProductType被约束为一个具体类型(ShopifyCollectionProduct<'uninformed'>),而非泛型类型。试图用ProductType<IsInformed>调用具体类型,必然报错。
正确写法(匹配原始意图)
如果你的需求是让ShopifyCollection的products属性对应ShopifyCollectionProduct<IsInformed>的数组,完全不需要把ShopifyCollectionProduct作为泛型参数传入——直接在接口内部使用该泛型类型别名即可:
export interface ShopifyPick<IsInformed extends Informed = 'informed'> { quantity: IsInformed extends 'informed' ? number : never } export type ShopifyCollectionProduct<IsInformed extends Informed = 'informed'> = ShopifyOneTimeBoxProduct | ShopifyGiftCardProduct | ShopifyPick<IsInformed> export interface ShopifyCollection<IsInformed extends Informed = 'informed'> { products: Array<ShopifyCollectionProduct<IsInformed>> | null }
进阶场景:支持自定义产品类型
如果需要让ShopifyCollection支持依赖IsInformed的自定义产品类型,可以将ProductType约束为ShopifyCollectionProduct<IsInformed>的子类型:
export interface ShopifyCollection< IsInformed extends Informed = 'informed', ProductType extends ShopifyCollectionProduct<IsInformed> = ShopifyCollectionProduct<IsInformed> > { products: Array<ProductType> | null }
这种写法既保留了泛型灵活性,又避免了类型调用错误。
内容的提问来源于stack exchange,提问作者Jonathan Tuzman

