Pick<> 不接受与 Omit<>

问题描述 投票:0回答:2

对于上下文,我想将一组可能的字符串值定义为类型。然后,我想限制该集合仅包含其中一些值,使用

Pick<>
来确保我对任何未来的添加保持弹性。

在 TypeScript 文档here中,提到

Omit
Pick
相反,所以我很惊讶地在这个用例中尝试使用
Pick
而不是
Omit
时遇到错误。

我设法让它与

Extract
而不是
Pick
一起工作,但我希望得到一些澄清。

这是一个最小的可重现示例:

const legalEntity = ['individual', 'company', 'ngo'] as const;
type LegalEntity = (typeof legalEntity)[number];

// Works
type NgoOnly = Omit<LegalEntity, 'individual' | 'company'>;

// Doesn't work, surprisingly
type IndividualOrCompanyPick = Pick<LegalEntity, 'individual' | 'company'>;

// Works as expected
type IndividualOrCompanyExclude = Extract<
  LegalEntity,
  'ngo'
>;

问题:

  1. 为什么
    Pick
    在这里没有按预期工作?
  2. 在这种情况下,
    Extract
    是限制联合类型中的一组值的最佳方法吗?

任何见解都会有帮助!

我尝试了上面的代码,我期望 Pick 以与 Omit 类似的方式工作,但事实并非如此。然后我用了Extract

typescript
2个回答
0
投票

Omit
允许任意键作为参数的问题。

如果您仅使用现有密钥来严格控制,您将收到错误:

游乐场

const legalEntity = ['individual', 'company', 'ngo'] as const;
type LegalEntity = (typeof legalEntity)[number];

type OmitLoose<T, K extends keyof any> = { [P in Exclude<keyof T, K>]: T[P]; } // the same as Omit
type OmitStrict<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P]; }


// Works
type NgoOnly = OmitStrict<LegalEntity, 'individual' | 'company'>; // error here

// Doesn't work, surprisingly
type IndividualOrCompanyPick = Pick<LegalEntity, 'individual' | 'company'>;

// Works as expected
type IndividualOrCompanyExclude = Extract<
  LegalEntity,
  'ngo'
>;

Pick
已经很严格了


0
投票

正如 @jared-smith 在他们的评论中所述,

Pick<T, Keys>
Omit<T, Keys>
适用于对象,而
Extract<T, Members>
Exclude<T, Members>
适用于联合类型,例如示例中的 LegalEntity

如果您使用 ExcludeExtract,您的示例将有效。 在下面的示例中,Extract 用于创建一个新类型,最终成为 ngo 的文字。 然后使用 ExludeLegalEntity 创建另一种类型,即不属于第一个创建的类型的所有内容。

const legalEntity = ['individual', 'company', 'ngo'] as const;
type LegalEntity = (typeof legalEntity)[number];

type NgoOnly = Extract<LegalEntity, 'ngo'>; // 'ngo'.
type IndividualOrCompany = Exclude<LegalEntity, NgoOnly>; // 'individual' | 'company'
© www.soinside.com 2019 - 2024. All rights reserved.