Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript ';CustomEnum.Case';可分配给类型为';T';,但是';T';可以使用约束的不同子类型';CustomEnum';_Typescript_Typescript Generics - Fatal编程技术网

Typescript ';CustomEnum.Case';可分配给类型为';T';,但是';T';可以使用约束的不同子类型';CustomEnum';

Typescript ';CustomEnum.Case';可分配给类型为';T';,但是';T';可以使用约束的不同子类型';CustomEnum';,typescript,typescript-generics,Typescript,Typescript Generics,我正在定义一个接口,其中属性类型之一依赖于绑定到枚举的泛型参数p。我采用以下方法: export enum Scopes { Fruit = 'fruit', Vegetables = 'vegetables', } export enum FruitItemTypes { Strawberry = 'strawberry', Rasberry = 'rasberry' } export enum VegetableItemTypes { Potatoes = 'pota

我正在定义一个接口,其中属性类型之一依赖于绑定到枚举的泛型参数p。我采用以下方法:

export enum Scopes {
  Fruit = 'fruit',
  Vegetables = 'vegetables',
}

export enum FruitItemTypes {
  Strawberry = 'strawberry',
  Rasberry = 'rasberry'
}

export enum VegetableItemTypes {
  Potatoes = 'potatoes',
  Carrots = 'currency',
}


export type ItemTypes = FruitItemTypes | VegetableItemTypes

interface ItemTypeForScope {
  [Scopes.Fruit]: FruitItemTypes;
  [Scopes.Vegetables]: VegetableItemTypes;
}

export interface Item {
  id: string;
  type: ItemTypes;
}
export interface ScopedItem<T extends Scopes> extends Item {
  type: ItemTypeForScope[T];
}
export interface ScopedData<T extends Scopes> {
  items: ScopedItem<T>[];
}

export type Data = { [scope in Scopes]: ScopedData<scope> };

导出枚举作用域{
水果=‘水果’,
蔬菜=‘蔬菜’,
}
导出枚举类型{
草莓=‘草莓’,
拉斯贝里=‘拉斯贝里’
}
导出枚举VegetableItemTypes{
土豆=‘土豆’,
胡萝卜=‘货币’,
}
导出类型ItemTypes=FruitItemTypes | VegetableItemTypes
接口项类型示波器{
[范围.水果]:水果类型;
[范围.蔬菜]:VegetableItemTypes;
}
导出接口项{
id:字符串;
类型:项目类型;
}
导出接口ScopedItem扩展项{
类型:ItemTypeForScope[T];
}
导出接口范围数据{
项目:ScopedItem[];
}
导出类型数据={[Scopes中的scope]:ScopedData};
我还想使用
ScopedItem
作为以下函数的返回类型:

const getItemType = <T extends Scopes>(data: Data, scope: T): ScopedItem<T>[] => {
    return data[scope].items 
}
const getItemType=(数据:数据,作用域:T):ScopedItem[]=>{
返回数据[scope]。项
}
然而,我得到了以下错误,但据我所知,泛型参数T最终将是enum案例之一

Type 'ScopedItem<Scopes.Fruit>[] | ScopedItem<Scopes.Vegetables>[]' is not assignable to type 'ScopedItem<T>[]'.
  Type 'ScopedItem<Scopes.Fruit>[]' is not assignable to type 'ScopedItem<T>[]'.
    Type 'ScopedItem<Scopes.Fruit>' is not assignable to type 'ScopedItem<T>'.
      Type 'Scopes.Fruit' is not assignable to type 'T'.
        'Scopes.Fruit' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Scopes'.
Type'ScopedItem[]| ScopedItem[]不可分配给Type'ScopedItem[]。
类型“ScopedItem[]”不可分配给类型“ScopedItem[]”。
类型“ScopedItem”不可分配给类型“ScopedItem”。
类型“Scopes.Fruit”不可分配给类型“T”。
“Scopes.Fruit”可分配给“T”类型的约束,但“T”可以用约束“Scopes”的不同子类型实例化。

我相信这里的问题与。。。您希望编译器将
{[K in Scopes]:ScopedData}[P]
计算为类似
ScopedData[P]
的值,其中
P
是扩展
K
的泛型类型参数。但编译器不会进行这种高阶推理,即在解析泛型类型之前对具体类型的泛型函数进行相似化;在某些情况下,有一种方法可以实现这一点,但在TS3.5中就没有了

所以,解决办法。。。编译器可以验证以下内容:

const getItemType = <T extends Scopes>(
  data: Data,
  scope: T
): Data[T]["items"] => {
  return data[scope].items;
};
const getItemType=(
数据:数据,
经营范围:T
):数据[T][“项目”]=>{
返回数据[范围]。项;
};
data[scope].items的类型作为
ScopedItem[]
返回,而不是将其作为
data[T][“items”]
返回。这些结果将是相同的,当您实际调用具体类型的
scope
参数上的
getItemType()
时,它将以相同的具体类型结束


或者,您可以承认您的推理能力优于编译器的推理能力,并使用a让编译器知道谁是老板:

const getItemTypeAssertion=(
数据:数据,
经营范围:T
):ScopedItem[]=>{

返回(数据[范围]作为ScopedData).items;//关于你的游乐场链接,我比编译器更聪明……这些不是并集和交集。你使用的是非常不同的。
x | | y
x&&y
将根据
x
的真实性/错误性,始终计算为
x
y
中的一个。谢谢你的详细解答r和问题参考,我相信
Data[T][“items”]
与编译器推断的类型相同。在这种情况下,类型断言似乎是一个很好的解决方案。关于逻辑运算符,这是一个漫长的一天,但感谢您在本例中对其无关性的反馈:)非常详细地介绍了此错误消息。请看一看。