2017-10-02 1 views
1

Je voudrais définir le typage d'un projet Javascript. Considérons une version simplifiée:Définition de type typographique espace de noms imbriqué avec interfaces

a 
| 
+ A.js 
+ b 
    | 
    + B.js 

Il y a un dossier « a », et à l'intérieur il y a dossier « b », et je voudrais l'utiliser comme:

import { A } from "a" 
import { B } from "a/b" 

Le typage que Je voudrais idéalement avoir ressemble à quelque chose comme ceci:

declare namespace a { 
    interface A { } 

    namespace b { 
     interface B { } 
    } 
} 

declare module "a" { 
    export = a 
} 

declare module "a/b" { 
    export = a.b 
} 

Cependant, cela me donne l'erreur Cannot use namespace 'a' as a value.

J'ai remarqué que si je change d'interface pour les classes, le problème se résout. Quelqu'un peut-il s'il vous plaît faire la lumière pourquoi c'est comme ça? Existe-t-il un moyen d'obtenir de telles définitions avec des interfaces?

Répondre

2

https://github.com/Microsoft/TypeScript/issues/17530

Un espace de noms qui ne contient aucune valeur ou des déclarations est considéré comme un espace de noms instancié, et n'a aucune valeur d'exécution.

Vous pouvez éviter l'erreur en faisant:

declare module "a/b" { 
    import b = a.b 
    export = b 
} 

Cependant, à moins que les namespaces a et a.b sont effectivement disponibles au niveauglobal lors de l'exécution, vous devez écrire:

declare module "a" { 
    export interface A { 
     foo: string 
    } 
} 

declare module "a/b" { 
    import {A} from 'a' 
    export interface B { 
     bar: A 
    } 
} 
+0

Qu'est-ce que vous signifie par "sauf si les espaces de noms a et ab sont réellement disponibles en tant que globals à l'exécution"? – Wickoo

+1

@Wickoo, c'est-à-dire que vous pouvez y accéder sans les importer, comme 'setTimeout' –