Есть ли способ различить тип объединения без выполнения оператора if? - PullRequest
0 голосов
/ 29 апреля 2020

Есть ли способ утвердить дискриминационное объединение без выполнения оператора if?

export type Maybe<T> = T | null | undefined;

export type Scalars = {
    String: string;
    GUID: string;
    DateTime: string;
};

export type Project = Node & {
    __typename?: 'Project';
    id: Scalars['GUID'];
    name: Scalars['String'];
    description?: Maybe<Scalars['String']>;
    logoUrl?: Maybe<Scalars['String']>;
    createdAt: Scalars['DateTime'];
    updatedAt: Scalars['DateTime'];
};

export type GetProjectForProjectDetailPageQuery = { __typename?: 'Query' } & {
    node?: Maybe<
        | { __typename?: 'Employee' }
        | { __typename?: 'JobTitle' }
        | ({ __typename?: 'Project' } & Pick<Project, 'id' | 'name' | 'description' | 'logoUrl' | 'updatedAt'>)
    >;
};

// Is there a way to assert the typename is Project without doing an if statement?
const x: GetProjectForProjectDetailPageQuery = {};

// Only picks up __typename field
x.node

// Works but requires an if statement. I'd like to eliminate the if statement.
if(x.node?.__typename === 'Project') {
    x.node.id    
    x.node.name     
    x.node.description    
    x.node.logoUrl    
}

Некоторый контекст:

Вышеуказанные типы генерируются GraphQL Code Generator, поэтому я не делаю у меня есть контроль над сгенерированными типами, меня интересуют поля вместе с Project __typename, и я заранее знаю, что так будет всегда, поэтому мне было интересно, есть ли способ исключить оператор if, чтобы различить union.

Edit:

Поиграл с предложениями @jcalz и придумал это на TS площадке , но пока не совсем там.

Хотелось бы чтобы получить безопасность типов для обобщенного c T, полученного из поля N __typename, если это возможно ...

// I'd like the generic T here to pickup possible values from the __typename field of generic N
type ExtractNode<N, T extends string> = Extract<NonNullable<N>, { __typename?: T }>

// What I expect
const node = {
    id: 'yes'
} as ExtractNode<GetProjectForProjectDetailPageQuery['node'], 'Project'>;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...