打字稿错误:“”仅指一种类型,但在此处用作命名空间

Posted

技术标签:

【中文标题】打字稿错误:“”仅指一种类型,但在此处用作命名空间【英文标题】:typescript error: ' ' only refers to a type, but is being used as a namespace here 【发布时间】:2021-01-07 23:12:44 【问题描述】:

我遇到了几个类似的问题,但无法解决这个问题。我一直在学习 2019 年的教程,但我无法找到在 2020 年做同样事情的正确方法。这是我遇到错误的行:

ERROR: 'HotelsQuery' only refers to a type, but is being used as a namespace here.ts(2702)

type IHotelsProps = HotelsQuery.Props<IHotelsBaseProps> & RouteComponentProps;

我从 generateModels 文件中传递 HotelsQuery,定义为:

export type HotelsQuery = (
   __typename?: 'Query' 
  &  hotels?: Maybe<(
     __typename?: 'HotelTypeConnection' 
    &  edges: Array<Maybe<(
       __typename?: 'HotelTypeEdge' 
      &  node?: Maybe<(
         __typename?: 'HotelType' 
        & Pick<HotelType, 'id' | 'title' | 'body'>
      )> 
    )>> 
  )> 
);

以及它被传递给的类:

class Hotels extends React.Component<IHotelsProps, IHotelsState> 
    constructor(props: IHotelsProps) 
        super(props);
        const query = queryString.parse(props.location.search);
        this.state = 
            searchQuery: query && query.search
            ? query.search.toString() : undefined
        ;
    

    public render() 
        const  searchQuery  = this.state;
        const  data  = this.props;

        return (
            <Row>
                <Col span=12 offset=6>
                    <Divider>Add Hotel</Divider>
                    <Divider>Hotels</Divider>
                    <Input.Search
                        placeholder="Search..."
                        enterButton="Search"
                        defaultValue=searchQuery
                        onChange=this.handleSearchQueryChange
                        onSearch=this.handleSearch
                    />
                    data!.loading ? (
                        <Spin style= marginTop: 16, display: 'block'  /> )
                        : (
                            <div>
                                data!.notes!.edges.map(edge => (
                                <Card
                                    key=edge!.node!.id
                                    style= marginTop: 16 
                                    actions=[
                                        <Icon
                                            type="delete"
                                            key=edge!.node!.id
                                            onClick=() => this.handleDeleteHotel(edge!.node!.id)
                                        />
                                    ]
                                >
                                    <Card.Meta
                                        title=edge!.node!.title
                                        description=edge!.node!.body
                                    />
                                </Card>
                            ))
                            </div>
                        )
                </Col>
            </Row>
        );
    

【问题讨论】:

您希望HotelsQuery.Props 解决什么问题? @TadhgMcDonald-Jensen 我刚刚将传递给它的类添加到最初问题中的代码中,如果有帮助吗? 不是真的,你说HotelsQuery 来自generatedModels 文件,这是否意味着它是自动生成的?是什么决定了该类型看起来像这样,因为它看起来肯定不会支持您尝试使用它的方式。 @TadhgMcDonald-Jensen 我使用 yarn generate 从我的 yml 文件生成模型。由于我正在学习一个不是最近的教程,因此我必须假设依赖项交互的方式与以前不同 HotelsQuery 是教程代码中的命名空间,而不是类型,因此解释了获取 Props 的语法,这是正确的和错误,因为您将其定义为类型。您的问题的根源是 HotelsQuery 定义不正确。它应该是一个带有 Props 属性的命名空间,这是一个泛型类型定义。我也不是说您上面对HotelsQuery 的定义应该是命名空间中Props 的定义。我没有完成教程。如果@TadhgMcDonald-Jensen 正在阅读本教程,他们将能够提供更多详细信息。 【参考方案1】:

所以我尝试了the tutorial 并想解释一些部分是如何工作的。

首先我只做了前端部分,所以当运行yarn gql-gen 时我遇到了障碍,因为codegen.yml 引用后端服务器来获取类型(我假设?)

overwrite: true
schema: "<http://localhost:8000/graphql/>"
documents: "src/**/*.ts"
generates:
    ./src/generatedModels.tsx:
        config: 
        plugins:
            - "typescript-common"
            - "typescript-client"
            - "typescript-react-apollo"

这里schema 指的是本地主机,所以我认为您需要正确配置后端以公开/graphql/ 目录中的类型。我刚刚收到一条错误消息,说我没有来源,所以要么这对你没有发生,因为你有后端设置或者你发现了另一个可能不正确的解决方法。

user@computer simplenote % yarn gql-gen --config codegen.yml
yarn run v1.22.5
$ /.../simplenote/node_modules/.bin/gql-gen --config codegen.yml
/.../simplenote/node_modules/graphql/jsutils/devAssert.js:12
    throw new Error(message);
    ^

Error: Must provide Source. Received: undefined.

我确实想指出,路径 node_modules/.bin/gql-gen 表示它实际使用的内容,即指向 node_modules/graphql-code-generator/__/cli.js 的链接,因此您实际与 yarn gpl-gen 一起使用的库是 graphql code generator,因此有关文档他们的网站可能会有所帮助。

所以我会推荐一些前进方向的选择:

    查看graphql TypeScript React Apollo 文档中的配置选项,自编写教程以来,默认选项可能已更改,特别是钩子正在大量替换 HOC,因此默认值可能不同。 当您运行yarn gql-gen 时重新检查后端部分是否正在运行,如果您在浏览器中转到http://localhost:8000/graphql/,我预计会有某种数据转储,否则codegen.yml 可能无法获取生成相关类型定义所需的信息。 放弃使用 HOC,因为它们很烂并转移到 using hooks,本教程的其余部分可能仍然有效,您只需要一个函数组件而不是一个类,并且可能使用生成的代码中的 useHotels。我强烈推荐使用钩子,它们如此迅速地取代了 HOC 是有充分理由的。

我希望这些中的一个或两个能引导你找到正确的方向来弄清楚如何继续,快乐的狩猎:)

【讨论】:

以上是关于打字稿错误:“”仅指一种类型,但在此处用作命名空间的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:错误 TS2693:“承诺”仅指一种类型,但在此处用作值

仅指一种类型,但在此处用作值

为啥 TypeScript 中的 'instanceof' 会给我错误“'Foo' 仅指一种类型,但在这里被用作值。”?

将 Require 语句替换为 Import 语句导致错误

使用反应创建上下文时找不到命名空间“ctx”错误 - 打字稿

打字稿:引用 Vuex 存储模块会导致 VueJs 2.5 的命名空间错误