Создайте объединение вне интерфейса, используя тег generic - PullRequest
0 голосов
/ 19 января 2020

У меня в настоящее время есть класс typeorm, который я ищу, чтобы иметь определенные функции c, где я могу "помечать" свойства с помощью этого Or generi c. Ниже в моем примере я использую интерфейс, но идея должна быть такой же.

Я хотел бы сделать что-то вроде этого:

export type Or<T, B> = T & { or?: undefined };

interface Example { 
  name: Or<string, 'firstName' | 'lastName'>
  firstName: Or<string, 'name'>
  lastName: Or<string, 'name'>
}

И я хотел бы передать Example в другое обобщение c Build<Example>, чтобы оно было примерно таким:

type UnionKeys<T> = T extends T? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends T? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, undefined>> : never;
export type StrictUnion<T> = StrictUnionHelper<T, T>

type E = StrictUnion<
  { firstName: string, lastName: string } |
  { name: string }
>

Возможно ли что-то подобное?

Обновление:

Это как-то в правильном направлении:

type Build<T> = StrictUnion<{ [P in keyof T]: T[P] extends { or: any } ? Pick<T, T[P]['or']> : never }[keyof T]>

const v:Build<Example> = { 
  name: 'hi'
}

1 Ответ

0 голосов
/ 19 января 2020
export type Or<T, B> = T & { or?: B };

interface Example { 
  name: Or<string, 'firstName' | 'lastName'>
  firstName: Or<string, 'name'>
  lastName: Or<string, 'name'>
}

type Build<T> = StrictUnion<{ [P in keyof T]: T[P] extends { or?: any } ? Pick<T, T[P]['or']> : never }[keyof T]>

type Working = Build<Example>

const a: Working = { 
  firstName: 'meow',
  lastName: 'woof'
}

const b: Working = { 
  name: 'meow'
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...