【问题标题】:How to import files which has nested namespace in typescript?如何在打字稿中导入具有嵌套命名空间的文件?
【发布时间】:2017-03-02 18:13:55
【问题描述】:

我正在将现有的 Node.js 项目转换为完全基于 TypeScript。我以前有一个静态的Sql 类(一个带有包含 MySQL 辅助函数的子对象的对象)。一个例子是Sql.user.findByIdSql 类还有一个 query 函数,用于执行原始 MySQL 查询,而无需暴露底层 MySQL 连接。

我现在想要的是一个名为 Sql 的命名空间,其中包含 query 函数,然后在曾经包含子类的文件中,我想要像 Sql.User 这样的命名空间,它可以导出像 @ 这样的函数987654329@.

问题是,我不知道如何嵌套这样的命名空间,同时能够访问嵌套命名空间中的query

我现在拥有的是这样的:

sql.ts:

import * as connection from "./connection";

export * from "./queries/confirmEmail";
export * from "./queries/resetPassword";
export * from "./queries/user";

namespace Sql {
    export function query( ...args: any[] ) {
        return connection.query( args );
    }

    export class Errors {
        static confirmCodeExpired = "45001";
        static confirmCodeNonExistent = "45002";
        static userAlreadyConfirmed = "45003";
    }
}

./queries/resetPassword.ts:

import "../sql";

namespace Sql.ResetPassword {
    type InsertCodeArgs = {
        code: string;
        userid: number;
        canChange: boolean;
    }

    export function insertCode( args: InsertCodeArgs, cb: Nodeback<void> ) {
        Sql.query(
            "CALL insert_reset_code( :code, :userid, :canChange );",
            {
                code: args.code,
                userid: args.userid,
                canChange: args.canChange ? 1 : 0
            },
            cb
        );
    }

    export function removeCode( code: string, cb: Nodeback<void> ) {
        Sql.query(
            "DELETE FROM `resetcodes` WHERE `code` = :code;",
            { code: code },
            cb
        );
    }

    export function checkCodeValid( code: string, cb: Nodeback<boolean> ) {
        Sql.query(
            [
                "SELECT NOW() <= `c`.`expires` AS `valid`, `c`.`canchange` as `canchange`, `u`.`id` AS `userid` FROM `resetcodes` AS `c` ",
                "INNER JOIN `users` AS `u`",
                "ON `u`.`id` = `c`.`userid`",
                "WHERE `code` = :code LIMIT 1;"
            ].join( " " ),
            { code: code },
            ( err, data ) => {
                if ( err ) return cb( err );
                if ( !data || data.length === 0 ) return cb( null, null );

                return cb( null, data[ 0 ].valid > 0, data[ 0 ].userid, data[ 0 ].canchange > 0 );
            }
        );
    }
};

然而,当我尝试编译时,我得到了一些看起来像这样的错误:

src\sql\queries\resetPassword.ts(11,13): error TS2339: Property 'query' does not exist on type 'typeof Sql'.

如何从父文件中“反向引用”查询函数?我当然不能import { Sql } from "../sql",因为Sql 是重复定义,我收到src/sql/sql.ts has no exported member "Sql" 的错误。

【问题讨论】:

  • 只是想知道为什么你使用命名空间而不是模块?
  • 我不确定如何使用 TypeScript 意义上的模块,所以如果这会是更好的方法,我会全力以赴。这在 Node 意义上是一个“模块”(一个 package.json 用于整个项目);我想更多的是按照我想的 C# 意义上的命名空间,那里会有一个包含所有 SQL 代码的子命名空间。
  • 您能否将现有的node.js 代码发布到js 中?我明天去看看
  • 我已经转换了它,但我可以从我的 git 历史记录中获取该文件。
  • 好的,这是旧的 Node.js JavaScript 代码。 gist.github.com/briman0094/d6cca72e3dce25ee80fbdfd8bf14eac7

标签: typescript


【解决方案1】:

我通过在子命名空间文件中别名导入父命名空间解决了我的命名空间引用问题:

import { Sql as sql } from "../sql";

...

namespace Sql.User {
    export function ... {
        sql.query(...);
    }
}

这允许Sql.User 命名空间使用来自另一个文件的Sql 命名空间中的函数。我仍然不知道如何将命名空间合并为一个,以便只需导入 sql.ts 即可导入 Sql.User 及其兄弟姐妹。我需要为此创建另一个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2020-06-30
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    相关资源
    最近更新 更多