当前位置: 首页 > 知识库问答 >
问题:

不允许将Typescript条件类型的有效解析类型映射回条件类型[duplicate]

林劲
2023-03-14

在报告bug之前,我想知道是否有办法做到这一点。以下是有关该问题的闪电战:https://stackblitz.com/edit/rxjs-wdvejf?file=index.ts

在下面的假设示例中,基于传入的枚举值(在本例中为映射键和函数参数),条件类型为BusinessPerson。Typescript正确地强制转换了AddressBookEntryType的使用。BusinessBusiness的实例,但即使BusinessAddressBookEntry的一种类型,如果没有hack(强制转换),也无法从函数返回Business值。

以下是条件类型:

type AddressBookEntry<T> = T extends AddressBookEntryType.Business
  ? Business
  : T extends AddressBookEntryType.Person
  ? Person
  : never;

和功能:

const addressBookMap: Map<
  AddressBookEntryType,
  Map<string, AddressBookEntry<any>>
> = new Map();

const getFromMap = <T extends AddressBookEntryType>(
  key: string,
  entryType: T
): AddressBookEntry<T> => {
  const byTypeMap = addressBookMap.get(entryType);
  if (byTypeMap !== null) {
    return byTypeMap.get(key); // <-- compiler error
  } else {
    return null;
  }
};

错误:

Type 'Business | Person' is not assignable to type 'AddressBookEntry<T>'.
  Type 'Business' is not assignable to type 'AddressBookEntry<T>'.(2322)

其余的代码:

interface Business {
  name: string;
}

interface Person {
  firstName: string;
  lastName: string;
}

// Now define an enumeration for what types may be stored in the address book:

enum AddressBookEntryType {
  Person,
  Business
}

解决方法/hack 1是将条件类型定义为any

type AddressBookEntry<T> = T extends AddressBookEntryType.Business
  ? Business
  : T extends AddressBookEntryType.Person
  ? Person
  : any; // <-- should be never here as there are no other valid options instead of any

这并不理想,因为这使得除了2个有效类型之外,似乎还有其他选项。

解决方案/黑客2将铸造结果:

const getFromMap = <T extends AddressBookEntryType>(
  key: string,
  entryType: T
): AddressBookEntry<T> => {
  const byTypeMap = addressBookMap.get(entryType);
  if (byTypeMap !== null) {
    return byTypeMap.get(key) as AddressBookEntry<T>;
  } else {
    return null;
  }
};

有没有一种方法可以做到这一点,而不需要演员阵容,工作环境或黑客,并保持它的“纯净”?

共有1个答案

司空宗清
2023-03-14

这个问题似乎抓住了我所看到的。

谢谢@jcalz

https://github.com/microsoft/TypeScript/issues/33912

 类似资料:
  • 本节介绍 TypeScript 高级类型中的条件类型(conditional type),条件类型就是在初始状态并不直接确定具体类型,而是通过一定的类型运算得到最终的变量类型。 1. 慕课解释 条件类型用来表达非均匀类型映射,可以根据一个条件表达式来进行类型检测,从两个类型中选出其中一个: T extends U ? X : Y 语义类似三目运算符:若 T 是 U 的子类型,则类型为 X,否则类

  • 我想基于泛型值返回不同的类型。例如: 但我有一个错误: 类型字符串[]不能分配给类型T扩展Base?String[]:字符串

  • TypeScript 会将一些好用的工具类型纳入基准库中,方便开发者直接使用,本节介绍的映射类型就是这样的工具类型。 对这种工具类型,我们不只要知道使用方法,还要了解其实现功能的本质。本节我们会从源码进行分析,逐步掌握。 1. 慕课解释 映射类型可以将已知类型的每个属性都变为可选的或者只读的。 2. Readonly 与 Partial 关键字 先来看这样一个任务:将 Person 接口的每个属性

  • 如何修复此问题: 如果T不是类类型,而是: 错误:“int”不是类、结构或联合类型24 |使用类型=std::conditional\u tstd::is\u class\u v 所以我不需要尝试调用错误的表达式,但是如何调用呢?

  • 我试图约束泛型函数的返回类型。(为了简化示例,请忽略函数的实际“有用性”)。 但是返回语句会导致打字错误- -这让我很困惑。在我的理解中,

  • 我对Flutter编程非常陌生,我正在尝试导入一个本地JSON文件,其中包含书籍数据,如标题、作者、发布年份等。 最初我使用JSON-to-DART转换器来组装一个图书数据模型,现在我正在尝试创建一个函数,在该函数中,程序获取本地JSON文件,并使用类中的方法将数据解析为地图。 我遇到的问题是返回类型