2017-03-02 4 views
0

Ich konvertiere ein vorhandenes Node.js-Projekt komplett auf TypScript-basiert. Ich hatte zuvor eine statische Sql Klasse (ein Objekt mit Unterobjekten, die MySQL-Hilfsfunktionen enthalten). Ein Beispiel wäre Sql.user.findById. Die Sql Klasse hatte auch eine query Funktion zum Ausführen von rohen MySQL-Abfragen, ohne die zugrunde liegende MySQL-Verbindung verfügbar zu machen.TypeScript verschachtelte Namespaces in separaten Dateien

Was würde ich mag nun ein Namespace Sql mit der query Funktion mit dem Namen, und dann in den Dateien, die die Unterklassen enthalten verwendet, würde ich Namespaces mag wie Sql.User dass Exportfunktionen wie findById.

Das Problem ist, ich kann nicht herausfinden, wie Namespaces so verschachteln, während query in den verschachtelten Namespaces zugreifen können.

Gerade jetzt, was ich habe, ist dies:

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); 
      } 
     ); 
    } 
}; 

Wenn ich versuche, und kompilieren, aber ich eine Reihe von Fehlermeldungen erhalten, die aussehen wie folgt:

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

Wie kann ich die Abfragefunktion von der übergeordneten Datei "zurückreferenzieren"? Ich kann nicht import { Sql } from "../sql" natürlich, weil dann Sql ist eine doppelte Definition, und ich bekomme einen Fehler, der src/sql/sql.ts has no exported member "Sql".

+0

nur wundern, warum Sie Namespaces anstelle von Modulen verwenden? –

+0

Ich bin mir nicht sicher, wie man Module im TypScript-Sinn verwendet, also wenn das ein besserer Weg wäre, es zu tun, bin ich ganz Ohr. Dies ist alles in einem "Modul" im Knoten Sinne (ein Paket.json für das gesamte Projekt); Ich denke eher an die Namespaces im C# -Sinne, wo es einen Sub-Namespace geben würde, der den gesamten SQL-Code enthält. – briman0094

+0

können Sie auch vorhandenen 'node.js' Code in' js' posten? Ich schaue morgen –

Antwort

1

ich meinen Namespace referenzieren Problem durch Alias-Import des übergeordneten Namespace in den untergeordneten Namespace-Dateien gelöst:

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

... 

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

Dies ermöglicht es die Sql.User Namespace-Funktionen im Sql Namespace aus einer anderen Datei zu verwenden. Ich weiß immer noch nicht, wie man die Namespaces zu einem zusammenfügt, so dass Sql.User und seine Geschwister einfach importiert werden können, indem man sql.ts importiert. Ich muss dafür eine andere Frage stellen.

Verwandte Themen