How can I export an interface that I have imported?
Asked Answered
B

6

18

I am creating a library in typescript, which is spread across multiple files. I take all the classes and constants I have defines and import them into one module, which exports them all under one namespace. I have just defines an interface, and I wish to include it in the same namespace/module as all the other parts of my library. But apparently I can't.

Here's a simplified example:

/app.ts is the entry point of the application, all I do in it at the moment is include my library MyLib:

//app.ts
import myLib = require("lib/MyLib/MyLib"); // this works fine

/lib/MyLib/MyLib.ts is the file in which I import all of the things defined by MyLib, and export them together:

// lib/MyLib/MyLib.ts

import VehiclesImport = require("./transport/vehicles");
// error under  VehiclesImport.IAutomobile, saying that VehiclesImport has no property IAutomobile
export var IAutomobile = VehiclesImport.IAutomobile; 
export var Car = VehiclesImport.Car;

In /lib/MyLib/transport/vehicles.ts, I define several classes and interfaces of vehicles, here, I'll just show IAutomobile and Car:

// lib/MyLib/transport/vehicles.ts

export interface IAutomobile {
    weight: number
}

export class Car implements IAutomobile {
    weight = 3000
}

I have tried creating a class truck in MyLib.ts, which properly implements IAutomobile, and that works fine, without any error messages. The problem only seems to arise when I want to access IAutomobile outside of an 'implements' statement.

I apologize if this seems like a 'code dump', but in my opinion, this is a serious problem that I cannot access my interfaces except in a class declaration. I have searched Google for the past two hours and found nothing on the subject. Thanks for any help you can give me!

Edit: I understand that typescript interfaces are not part of the compiled javascript code, but that should not stop me from manipulating them within typescript.

Brainy answered 28/7, 2014 at 16:32 Comment(0)
U
14

Use the import keyword to bring in something into the type declaration space (as opposed to var which brings it into the variable declaration space).

This is demonstrated below. a.ts:

export interface A {
    val: number;
}

To re-export this from another file b.ts:

import a = require('./a');
export import B = a.A; // Important use of import

Sample usage in some other file c.ts:

import b = require('./b');

var foo: b.B;
foo.val = 123;

interface C extends b.B {
    val2:number;
}

var bar: C;
bar.val2 = 456;
Unbelt answered 28/7, 2014 at 23:22 Comment(4)
Very useful explanation and solution, thank you. I just have one question, will b.B be useable as an interface in c.ts?Brainy
@Brainy be useable as an interface in c.ts already done in foo:b.B. If you meant extendable updated answer to demonstrate that as well.Unbelt
Yes that is what I meant, sorry for the confusion I wrote that fairly late at night. Thanks so much! I wasn't sure I'd be able to get around this problem.Brainy
import a = require('./a') is invalid syntax.Danilodanio
C
14

The example rewritten following TS language specification:

a.ts:

export interface A {
   val: number;
}

To re-export this from another file b.ts:

export {A} from './a'

Usage in some other file c.ts:

import {A} from './b'

var foo: A = {val: 2};
foo.val = 123;

interface C extends A {
    val2:number;
}

var bar: C = {val: 1, val2: 3};
bar.val2 = 456;
Copy answered 26/1, 2018 at 10:6 Comment(1)
I prefer this answer over the accepted answer as it does not use require and supports easily reexporting multiple types and values selectively rather than broadly.Sg
I
7

Types can't be assigned to variables, they exist in different "declaration spaces". Classes can be assigned to variables, because they contribute their names to the type declaration space as well as defining the class objects. Interfaces only contribute to the types declaration space, so can't be referenced as values.

The language is a bit verbose, but this is spelt out in detail in section 2.3 of the language spec

Iyar answered 28/7, 2014 at 22:27 Comment(2)
Great explanation, and a helpful link, the only reason I hesitate to mark it as the accepted answer is that it lacks any workaround/solution, when other answers have provided one.Brainy
Thanks, updated the link to current version of the doc.Iyar
M
4

This works to re-export types/interfaces

import type { MyInterface, MyType } from './randomModule';

export { MyInterface, MyType }

The key is the surrounding braces in the export statement. Works in TypeScript 4.7.4. Reference.

Mayorga answered 28/2, 2022 at 23:55 Comment(2)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Seminal
Nice and clean!Sheepdog
E
3

foo.ts

export interface ITest {
  ...
}

bar.ts

import * as foo from "./foo";

export type ITest = foo.ITest;
Ezequieleziechiele answered 25/6, 2019 at 11:54 Comment(1)
will this implicitly convert interface into a type?Concentration
G
0

In TypeScript 3.9.6, this worked for me:

import { Foo as FooType } from './some-path';

export type Foo = FooType;
Grand answered 17/11, 2022 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.