首页 > 解决方案 > 省略助手不适用于映射对象类型

问题描述

我正在尝试使用Omit实用程序类型来创建映射类型,但它给了我一个错误。请考虑以下示例:

我有一个像这样的文字类型

type something = 'abc' | 'bcd' | 'cde' | 'def';

我想创建一个这样的映射类型

type mappedType = {
    [k in something]: string;
}

这相当于

type mappedType = {
  abc: string;
  bcd: string;
  cde: string;
  def: string;
}

这很好用,但让我们考虑是否要省略一个属性。

type mappedTypeWithOmit = {
    [k in Omit<something, "def">]: string;
}

上面的代码不起作用。而如果我使用Exclude而不是Omit,我能够得到想要的结果:

type mappedTypeWithExclude = {
    [k in Exclude<something, "def">]: string;
}

这很奇怪,因为 Omit 应该给出相同的结果,因为它也在引擎盖下使用了 Exclude

/**
 * Construct a type with the properties of T except for those in type K.
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

点击查看 typescript repo 中的代码

我得到的错误是

Type 'Omit<something, "def">' is not assignable to type 'string | number | symbol'.
  Type 'Omit<something, "def">' is not assignable to type 'string'.

你也可以在TypeScript Playground中查看

请帮助我理解我做错了什么。

标签: typescript

解决方案


省略用于接口或对象类型,我们正在尝试在联合字符串文字上使用它。这就是错误的原因。

用法:

type mappedType = {
  abc: string;
  bcd: string;
  cde: string;
  def: string;
}

type mappedTypeWithOmit = Omit<mappedType,'def'>

这将相当于

type mappedTypeWithOmit = {
  abc: string;
  bcd: string;
  cde: string;
}

排除不同,它用于排除联合类型。

用法:

type something = 'abc' | 'bcd' | 'cde' | 'def';
type somethingWithExclude = Exlude<something, "def">

这将相当于

type somethingWithExclude = 'abc' | 'bcd' | 'cde';

现在我们可以继续使用它来创建映射类型。

type mappedTypeWithExclude ={
  [k in somethingWithExclude]: string;
}

这将相当于

type mappedTypeWithExclude = {
  abc: string;
  bcd: string;
  cde: string;
}

阅读Difference b/w Exclude and Omit了解更多信息。


推荐阅读