Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use namespaces with import in TypeScript

I have two classes in two separate files and one extends from another. The base class contains some import statements using node modules. It is unclear to me why the derived class (which is in a separate file) does not recognize the base class!!!???

Can someone clarify this please?

// UtilBase.ts  /// <reference path="../typings/node.d.ts" /> /// <reference path="../typings/packages.d.ts" />  import * as path from "path"; // <---- THIS LINE BREAKS THE BUILD!!!!  namespace My.utils {      export class UtilBase {          protected fixPath(value: string): string {             return value.replace('/', path.sep);         }    } } 

And then

// UtilOne.ts /// <reference path="UtilBase.ts" />  namespace My.utils {      export class UtilOne extends My.utils.UtilBase {      } } 

After compiling I get:

src/UtilOne.ts(6,47): error TS2339: Property 'UtilBase' does not  exist on type 'typeof utils' 
like image 966
gevik Avatar asked Jun 01 '16 10:06

gevik


People also ask

How do you namespace in TypeScript?

The namespace is used for logical grouping of functionalities. A namespace can include interfaces, classes, functions and variables to support a single or a group of related functionalities. A namespace can be created using the namespace keyword followed by the namespace name.

Should you use namespace in TypeScript?

Modern code should use the ES Module syntax, as it has all the features provided by namespaces, and starting with ECMAScript 2015 it became part of the specification. However, when creating module declarations, the usage of namespaces is still recommended as it allows for more concise type declarations.

Can I use import in TypeScript?

With TypeScript 3.8, you can import a type using the import statement, or using import type .


1 Answers

A solution with namespaces (not recommended)

To resolve your issue, you can export your namespace:

// UtilBase.ts import * as path from "path"; export namespace My.utils {     export class UtilBase {         protected fixPath(value: string): string {             return value.replace('/', path.sep);         }    } } 

Then, you should be able to import it:

// UtilOne.ts import {My} from './UtilBase'; namespace My.utils {     export class UtilOne extends My.utils.UtilBase {     } } 

However, if the purpose is to organize the code, it is a bad practice to use namespaces and (ES6) modules at the same time. With Node.js, your files are modules, then you should avoid namespaces.

Use ES6 modules without namespaces

TypeScript supports the syntax of ES6 modules very well:

// UtilBase.ts import * as path from "path"; export default class UtilBase {     protected fixPath(value: string): string {         return value.replace('/', path.sep);     } }  // UtilOne.ts import UtilBase from './UtilBase'; export default class UtilOne extends UtilBase { } 

It is the recommended way. ES6 modules prevent naming conflicts with the ability to rename each imported resource.

It will work on Node.js (using the commonjs module syntax in compiler options).

For a good introduction to the ES6 modules syntax, read this article.

Use a file tsconfig.json instead of /// <reference

Notice: The syntax /// <reference is replaced by the file tsconfig.json. An example for Node.js:

// tsconfig.json {   "compilerOptions": {     "module": "commonjs",     "target": "es6"   },   "exclude": [     "node_modules"   ] } 
like image 128
Paleo Avatar answered Sep 18 '22 04:09

Paleo