如何让 TypeScript 对扩展从“节点模块”导入的类感到满意?

Posted

技术标签:

【中文标题】如何让 TypeScript 对扩展从“节点模块”导入的类感到满意?【英文标题】:How to make TypeScript happy with extending classes imported from 'node modules'? 【发布时间】:2020-06-14 15:04:43 【问题描述】:

编辑:按要求添加了ARTICLES_QUERYtsconfig.jsonpackage.json

编辑 2:这可行,但它似乎是一个丑陋的解决方案。如果有人有更好的,我将不胜感激

export default class InterfaceGraphQLApi extends GraphQLDataSource 
  baseURL = "http://localhost:4545/admin/api";

  query = super.query;

编辑 3:@Max 的解决方案解决了查询字段的问题,但它导致 TS 由于另一个“错误”而无法编译源:

ARTICLE_QUERY这里是

const ARTICLE_QUERY = gql`
  query Article($id: ID!) 
    Article(where:  id: $id ) 
      title
      text
      video 
        youtube 
          ... on OEmbedVideo 
            html
            type
          
        
      
      podcast 
        spotify 
          ... on OEmbedRich 
            html
            type
          
        
      
      images 
        file 
          filename
        
      
    
  
`;

编辑 4:Max 编辑后的解决方案运行良好。


我对 TypeScript 比较陌生。我正在导入一个library,它允许我为我的 Apollo Server 项目定义一个 GraphQL 数据源。在我的项目中,我正在扩展这个库定义的类

 import  GraphQLDataSource  from "apollo-datasource-graphql";
import  gql  from "apollo-server";

const ARTICLES_QUERY = gql`
  query 
    allArticles 
      title
      text
      id
      status
      images 
        file 
          filename
        
      
    
  
`;

export default class InterfaceGraphQLApi extends GraphQLDataSource 
      baseURL = "http://localhost:4545/admin/api";

      async getArticles() 
        try 
          const response = await this.query(ARTICLES_QUERY);

然而 TypeScript 抱怨 this.query,说

query 方法来自导入库的类。我该如何解决这个问题才能让 TypeScript 满意?

tsconfig.json 是


  "compilerOptions": 
    "target": "ESNext",
    "lib": [
      "esnext",
      "dom"
    ],
    "skipLibCheck": true,
    "outDir": "dist",
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "sourceMap": true
  ,
  "exclude": [
    "node_modules"
  ]

而 package.json 是


  "dependencies": 
    "apollo-datasource-graphql": "^1.3.2",
    "apollo-server": "^2.10.1",
    "graphql": "^14.6.0"
  ,
  "devDependencies": 
    "babel-eslint": "^10.0.3",
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.0.0",
    "eslint-config-prettier": "^6.10.0",
    "eslint-plugin-prettier": "^3.1.2",
    "pino": "^5.16.0",
    "prettier": "^1.19.1",
    "ramda": "^0.26.1",
    "typescript": "^3.8.3"
  ,
  "scripts": 
    "dev": "tsc && node dist/index.js"
  

此外,我想知道是否有人可以引导我使用 Apollo Server 和 GraphQL 所需的类型定义——我搜索了“类型定义 Apollo Server”并想出了 this,但它有我还必须查找和下载许多依赖项。我想知道是否有类似@types/apollo-server 的东西(当我使用yarn @types/apollo-server 时,我得到了https://registry.yarnpkg.com/@types%2fapollo-server: Not found.)。

感谢您提供任何信息!

【问题讨论】:

能否将您的 ARTICLES_QUERY 添加到您的问题中? @Max -- 已添加 Typescript 在运行时会抱怨吗? 而gql来自import gql from 'apollo-server-express';?而 GraphQLDataSource 来自import GraphQLDataSource from 'apollo-datasource-graphql';? 并发布您的 tsconfig 和 package.json 将有助于回答您的问题。我已经创建了一个 stackblitz stackblitz.com/edit/typescript-zdysny,它在其中编译 【参考方案1】:

apollo-datasource-graphql repo 中有一个公开的 PR:https://github.com/poetic/apollo-datasource-graphql/pull/11

同时有一个解决方案可以帮助您。更改您的导入来源:

import GraphQLDataSource from 'apollo-datasource-graphql';

import GraphQLDataSource from 'apollo-datasource-graphql/src';

最后,我在研究过程中发现了一个有趣的部分。我在apollo server 的文档中找到了一个部分,您可以在其中将 api 定义为资源而不是 graphql 服务器。您提供的代码实际上就是这种情况。

另外,如果你有其他问题可能会阻止 tsc 编译,请在你的 node_modules 下进入 apollo-datasource-graphql 文件夹并进入查询功能。 options 参数有所需的类型。正如文档所说,您需要在选项中提供作为第一个参数传递的查询作为这样的查询

const response = await this.query(ARTICLE_QUERY, query: ARTICLE_QUERY, variables: id );

【讨论】:

解决了原始问题,但导致了另一个阻止 TS 编译的问题。我编辑了原始问题以指出该错误。感谢您提供指向这些文档的指针——据我所知,这仅适用于 REST 源,因此需要 apollo-datasource-graphql @Cerulean:如果您还有其他问题,请打开我可以帮助您的 stackblitz 或 typescript playground。您的第一个问题中的查询已得到回答,当您更改查询时,会出现另一个问题。或者打开一个 github 存储库,我可以帮助你。我更改了您上次编辑的答案。 如果我需要进一步的东西,我会尝试上传一些东西。我将字段 query 添加到 options 并且效果很好。但是,当我尝试编译和编译停止时,我现在得到Error: Cannot find module 'apollo-datasource-graphql/src'。以前用过,很奇怪。

以上是关于如何让 TypeScript 对扩展从“节点模块”导入的类感到满意?的主要内容,如果未能解决你的问题,请参考以下文章

如何从节点模块中的@types 保存类型

Typescript 从节点模块导入 ts 文件

如何使用 CLI 将带有节点模块的 TypeScript Web 应用程序编译成一个 JavaScript 文件? [关闭]

使用 TypeScript 导入节点模块

如何在 Typescript 1.8 中包含无类型节点模块?

手动注册节点模块