【问题标题】:Does typescript not check types on the result of an Array.map?typescript 不检查 Array.map 结果的类型吗?
【发布时间】:2019-06-24 00:40:51
【问题描述】:
interface Company {
  id: string;
  name: string;
}

type input = Company;

// This fails as the types don't match
const ACME: input = { id: '123', name: 'ACME', ceo: 'Eric' };

function mapIds(ids: string[]): input[] {
  // This compiles, but it shouldn't, or is Array.map returning something different?
  return ids.map(id => ({ id: '1', name: '1', ceo: 'Eric' }));

  // This fails as types don't match
  return [{ id: '1', name: '2', ceo: 'Eric' }];
}


鉴于上述代码,typescript 编译器将不允许函数返回不属于该类型的值,但如果返回来自 Array.map,则允许。您可以在 Typescript Playground 上使用上述 sn-p 看到这一点:https://www.typescriptlang.org/play/

谁能解释一下这是怎么回事?

【问题讨论】:

    标签: arrays typescript dictionary


    【解决方案1】:

    您的 map 函数没有指定返回类型,因此它可以返回任何内容。如果你想要更严格的检查,你需要明确:

    interface Company {
      id: string;
      name: string;
    }
    
    type input = Company;
    
    // This fails as the types don't match
    const ACME: input = { id: '123', name: 'ACME', ceo: 'Eric' };
    
    function mapIds(ids: string[]): input[] {
      return ids.map((id):Company => ({ id: '1', name: '1', ceo: 'Eric' }));
    
      // This fails as types don't match
      return [{ id: '1', name: '2', ceo: 'Eric' }];
    }
    

    原因是.map 函数是一个映射操作,旨在将数组中的每个元素转换为新类型。如果您不指定,TypeScript 不知道新类型将是什么。

    扩展下面的 cmets。 TSC 反对return [{ id: '1', name: '2', ceo: 'Eric' }]; 行,因为它需要input[] 类型,但它不是。但是 ids.map(id => ({ id: '1', name: '1', ceo: 'Eric' })); 本身很好(因为 .map 可以返回任何类型),然后 分配input[] 这是允许的。

    感谢 @TitianCernicova-Dragomir 和 @p.s.w.g 对此的 cmets。

    【讨论】:

    • 地图的返回类型被标识为{ id: string; name: string; ceo: string; }[]——这很好。我认为问题是为什么 tsc 在您尝试将该值作为input[] 返回时没有抱怨,但在尝试直接返回[{ id: '1', name: '2', ceo: 'Eric' }] 时却失败了?
    • @p.s.w.g 因为 TS 只会在将对象文字直接分配给预期为特定类型的东西时抱怨过多的属性检查。在这种情况下,map 调用是独立类型的,返回类型是类型为{ id: string , name: string , ceo: string }[] 类型的数组。然后将其分配给 input[] 类型的数组,这是允许的,并且不会执行过多的属性检查
    • @TitianCernicova-Dragomir 很好的解释。我认为要让答案被认为是完整的,它应该包括这些细节。
    • @pswg 我同意,apokryfos 可以随意包含该评论的任何部分,如果他愿意,他的解决方案与我发布的代码相同,所以我不会自己添加答案
    • 感谢 cmets。我已经更新了我的答案,希望能涵盖细节。
    猜你喜欢
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 2020-10-29
    • 2020-04-03
    • 2012-09-29
    • 2021-11-14
    相关资源
    最近更新 更多