首页 > 解决方案 > 分配类型以匹配变量类型

问题描述

我正在尝试创建一个小函数,该函数将采用 apple | 类型的数组。橙色 | 梨 | mango 并将其转换为一个相应的定制字典接口,它只是一个对象。

我的代码:

  private mapArrayToDictionary = (
    array:
      | Apple[]
      | Orange[]
      | Pear[]
      | Mango[]
  ) => {
    const sorted: Dictionary<typeof array> = {};
    array.map((fruit) => (sorted[fruit.id] = fruit));
    return sorted;
  };

我正在尝试将返回的数组动态分配为与作为参数传入的数组相同的类型。然后我将把那个id作为key,把value作为fruit对象本身。

我收到错误“类型'Apple'不可分配给类型'Orange [] | Pear [] | Mango []。等等。

我假设我可以只制作一个通用的水果接口类型,但我不明白为什么这种“数组类型”不能延续。谢谢

编辑:我的功能适用于所有相同的属性水果

function mapArrayToDictionary(
  array:
    | Apple[]
    | Orange[]
    | Mango[]
) {
  type AnyFruitArray =
    | Apple
    | Orange
    | Mango;

  const sorted: Dictionary<AnyFruitArray> = {};
  array.map(item => (sorted[item.id] = item));
  return sorted;
}

我的水果界面:

export interface Fruit {
  name: string;
  type: string;
}

export interface Apple extends Fruit{
  id: number;
}

export interface Pear extends Fruit {
    id: number;
    location_id: number;
    location_name: string;
    producer: string;
}

我如何调用函数:

const apples = await CalAPI.fetchApplesByIds(fruitIds);
this.setState({ relApples: mapArrayToDictionary(apples)});

标签: typescript

解决方案


泛型救援:

private mapArrayToDictionary = <T extends { id: string | number }>(
  array: T[]
) => {
    const sorted: Dictionary<T> = {};
    array.map((fruit) => (sorted[fruit.id] = fruit));
    return sorted;
};

请注意,Fruit它没有属性id,因此您将无法简单地使用<T extends Fruit>,但如果您想将此方法限制为仅接受也实现 的字段的类型Fruit,我建议您使用交集类型 <T extends Fruit & { id : string | number }>

或者,如果您只需要处理几个已知的水果类型(并假设所有这些类型都包含有效id属性),您可以将这些已知的水果类型合并:

type KnownFruit = Apple | Orange | Pear | Mango;
...

private mapArrayToDictionary = <T extends KnownFruit>(
  array: T[]
) => {
    const sorted: Dictionary<T> = {};
    array.map((fruit) => (sorted[fruit.id] = fruit));
    return sorted;
};

推荐阅读