Сложное обобщенное ограничение типа c - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь написать функцию getDocument, которая будет выполнять следующее:

interface DocumentReference<T> {
  get(): Promise<T>;
}

interface ParentA {
  foo: DocumentReference<User>;
}

interface ParentB {
  bar: DocumentReference<Company>;
}

// getDocument<ParentType>(parent: ParentType, fieldName: keyof ParentType): Promise<???>
getDocument(parentA, 'foo') // return a Promise<User>
getDocument(parentB, 'bar') // return a Promise<Company>

Я пробовал много разных комбинаций обобщенных c подписей для getDocument, но могу ' t выяснить, как ограничить fieldName, чтобы оно соответствовало значению поля типа DocumentReference. Я не знаю, как извлечь обобщенный c параметр DocumentReference<T> в возвращаемый тип.

Это возможно в машинописи? Если да, какие-нибудь указатели?

1 Ответ

0 голосов
/ 10 апреля 2020
interface User {
    a: number
}
interface Company {
    b: string
}
interface DocumentReference<T> {
    get(): Promise<T>;
}

interface ParentA {
    foo: DocumentReference<User>;
}

interface ParentB {
    bar: DocumentReference<Company>;
}

declare function getDocument<T extends ParentA | ParentB, K extends keyof T>(value: T, key: K): Promise<T[K] extends DocumentReference<infer R> ? R : never>;
declare const parentA: ParentA
declare const parentB: ParentB
getDocument(parentA,'foo')
getDocument(parentB,'bar')
...