【问题标题】:Allocating a Type so it Matches a Variables Type分配类型以匹配变量类型
【发布时间】:2019-08-10 13:47:40
【问题描述】:

我正在尝试创建一个小函数,该函数将采用 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


    【解决方案1】:

    Generics 救援:

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

    请注意,Fruit 没有属性 id,因此您将无法简单地使用 &lt;T extends Fruit&gt;,但如果您想将此方法限制为仅接受也实现了 @ 字段的类型987654327@,我推荐intersection type &lt;T extends Fruit &amp; { id : string | number }&gt;

    或者,如果您只需要处理几种已知的水果类型(并且假设所有这些类型都包含有效的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;
    };
    

    【讨论】:

    • 我无法让第二个解决方案工作,因为我收到错误“Pear 不可分配给类型 T”。第一个解决方案似乎可以正常工作,但前提是所有水果都具有相同的特性。如果 Pear 有一个额外的属性,那么我会得到一个错误。有没有办法解决这个问题?
    • @C.Programming 你能展示一下ApplePear 等的实际样子,以及你是如何调用这个方法的吗?
    • @C.Programming 在您更新的问题中,Pear 没有id 属性,因此它不满足T 的约束。您可以将id: string 移动到您的基本Fruit 接口,或者使用nametype 来索引sorted 而不是id
    • 抱歉,pear 确实有 id 属性
    • @C.Programming 我现在明白这个问题了。 id 是一个数字而不是一个字符串。我已更新我的答案以反映新信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多