有条件申请?映射类型中的修饰符 per-属性

Conditionally apply ? modifier in mapped type per-property

来自 TypeScript 文档:

// Removes 'optional' attributes from a type's properties
type Concrete<Type> = {
  [Property in keyof Type]-?: Type[Property];
};

type MaybeUser = {
  id: string;
  name?: string;
  age?: number;
};

我知道我可以将 ? 修饰符添加到 所有 属性,如果我想根据 属性 添加它 属性 怎么办在 extends 表达式上?

行为会像这样的东西:

// Not valid TypeScript
type Optionalize<T> = {
   [P in keyof T](?: T[P] extends SomeInterface): T[P];
}   

相关 GitHub 问题:https://github.com/microsoft/TypeScript/issues/32562

  1. 提取类型中不匹配的道具,我们称之为NonMatching
  2. 提取第二种类型的匹配道具,比如Matching
  3. 使用 extends infer 技巧将两种类型相交
type TestType = {
  a: SomeInterface;
  b: string;
};

type Intersection<A, B> = A & B extends infer U
  ? { [P in keyof U]: U[P] }
  : never;

type Matching<T, SomeInterface> = {
  [K in keyof T]: T[K] extends SomeInterface ? K : never;
}[keyof T];

type NonMatching<T, SomeInterface> = {
  [K in keyof T]: T[K] extends SomeInterface ? never : K;
}[keyof T];

type DesiredOutcome = Intersection<
  Partial<Pick<TestType, Matching<TestType, SomeInterface>>>,
  Required<Pick<TestType, NonMatching<TestType, SomeInterface>>
>

{[K in keyof T]: T[K] extends SomeInterface ? K : never } 将每个匹配的键映射到它自己的 字符串文字类型表示 是一种解决方法,即给定 { a: never, b: SomeInterface } 你得到 { b: 'b' },然后使用 indexed access types 可以得到 字符串文字类型联合形式的匹配属性