Добавление объединений с тегами typescript в результат запроса graphql в gatsby - PullRequest
1 голос
/ 20 июня 2020

Я использовал Объединения с тегами Typecript для проверки типа, какой интерфейс использует аргумент функции. Вот два интерфейса, каждый из которых может быть передан в функцию fun c ниже

export interface IPubArticle {
  kind: "IPubArticle"
  node: {
    fields: {
      slug: string
    }
    frontmatter: {
      title: string
      category: string
      author: string
      issue: string
      date: string
      givenRank: number
    }
  }
}

export interface IArticleSquare{
  kind: "IArticleSquare"
  node: {
    fields: {
      slug: string
    }
    frontmatter: {
      title: string
      subTitle: string
      category: string
      author: string
      featuredImage: {
        childImageSharp: IFluidObject
      }
      date: string
      givenRank: number
    }
  }
}

const func = ({data}: {data: IArticleSquare | IPubArticle}) => {
    switch (data.kind){
        case "IArticleSquare":
            ...
        case "IPubArticle":
            ...
    }
}

Теперь у меня проблема, потому что, по-видимому, мой вызов graphql не соответствует интерфейсу, потому что тип переменной отсутствует

Argument of type '{ node: { fields: { slug: string; }; frontmatter: { title: string; subTitle: string; date: string; description: string; category: string; author: string; givenRank: number; featuredImage: { childImageSharp: GatsbyImageProps; }; }; }; }[]' is not assignable to parameter of type 'IArticleSquare[]'.
  Property 'kind' is missing in type '{ node: { fields: { slug: string; }; frontmatter: { title: string; subTitle: string; date: string; description: string; category: string; author: string; givenRank: number; featuredImage: { childImageSharp: GatsbyImageProps; }; }; }; }' but required in type 'IArticleSquare'.ts(2345)
article.interface.ts(21, 3): 'kind' is declared here.

А вот мой запрос graphql

export const pageQuery = graphql`
  query($path: string!) {
    allMarkdownRemark(
      sort: { order: DESC, fields: [frontmatter___date] }
    ) {
      edges {
        node {
          fields {
            slug
          }
          frontmatter {
            title
            subTitle
            date(formatstring: "MMMM DD, YYYY")
            category
            featuredImage {
              childImageSharp {
                fluid(maxWidth: 400) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    }

Как я могу это исправить? Я действительно понятия не имею, что делать

1 Ответ

1 голос
/ 21 июня 2020

Предполагая, что IArticleSquareNode всегда имеет subtitle в frontmatter, а IArticleNode его нет, вы можете написать User-Defined Type Guard (isSquareNode), чтобы помочь вам идентифицировать тип узла.

interface IFrontmatter {
  title: string
  category: string
  author: string
  issue: string
  date: string
  givenRank: number
}

interface IFrontmatterSquare extends IFrontmatter {
  subTitle: string
}

interface IFields {
  slug: string
}

interface IArticleNode {
  fields: IFields
  frontmatter: IFrontmatter
}

interface IArticleSquareNode {
  fields: IFields
  frontmatter: IFrontmatterSquare
}

function isSquareNode(
  node: IArticleSquareNode | IArticleNode,
): node is IArticleSquareNode {
  return (node as IArticleSquareNode).frontmatter.subTitle !== undefined
}

const func = (node: IArticleSquareNode | IArticleNode) => {
  if (isSquareNode(node)) {
    return 'is of type IArticleSquareNode'
  } else {
    return 'is of type IArticleNode'
  }
}

const testArticleNode = {
  fields: {
    slug: '/myslug/',
  },
  frontmatter: {
    title: 'title',
    category: 'category',
    author: 'author',
    issue: 'issue',
    date: 'date',
    givenRank: 1,
  },
}

const testArticleSquareNode = {
  fields: {
    slug: '/myslug/',
  },
  frontmatter: {
    title: 'title',
    subTitle: 'subTitle',
    category: 'category',
    author: 'author',
    issue: 'issue',
    date: 'date',
    givenRank: 1,
  },
}

console.log(func(testArticleNode)) // is of type IArticleNode
console.log(func(testArticleSquareNode)) // is of type IArticleSquareNode 
...