Условно подать заявку? модификатор в сопоставленном типе для каждого свойства

Из документов 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];
}   

person Davide Valdo    schedule 16.05.2021    source источник
comment
Отвечает ли это на ваш вопрос? Отображаемый тип Typescript, условно добавьте необязательный модификатор   -  person cherryblossom    schedule 16.05.2021
comment
Я думал, что это не так, но, читая лучше, это могло быть.   -  person Davide Valdo    schedule 16.05.2021
comment
Это вроде как, но не полностью   -  person Davide Valdo    schedule 18.05.2021


Ответы (1)


Соответствующая проблема 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' }, затем используйте индексированные типы доступа вы получите соответствующие свойства в виде объединения типов строковых литералов

person Davide Valdo    schedule 17.05.2021