Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular Type References in TypeScript

Tags:

typescript

I am new to typescript and am trying to understand how I can setup a circular reference between two types. The reference need not be a full code reference, simply the interfaces, but with interfaces defined in separate files. For example, let's say I have two interfaces: Parent and Child. They are doubly-linked such that the parent has a collection of children and each child has a reference to the parent (as seen below). How do I setup the imports or dependencies so that these can be defined in separate files?

interface Parent {   children: Child[] }  interface Child {   parent: Parent } 
like image 854
Viper Bailey Avatar asked Jun 27 '14 05:06

Viper Bailey


People also ask

What is circular dependency in typescript?

In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.

How to check circular dependency in typescript?

By running a cli command npx madge --circular --extensions ts ./ we can quickly get a list of circular dependencies of all . ts files in current directory and its subdirectories.


2 Answers

I also faced with the similar situation.

I could resolve by using import type.

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html

like image 83
mozu Avatar answered Sep 20 '22 15:09

mozu


Two solutions below. I prefer the latter since it offers clean interfacing with Node JS modules, but unfortunately my IDE doesn't (yet) like it as much as I do...

Use references

Create a definitions.d.ts file that will only contain the references to your classes/interfaces

/// <reference path="Parent.ts" /> /// <reference path="Child.ts" /> 

In Parent.ts and Child.ts, point to a single reference, the definitions.d.ts file

/// <reference path="definitions.d.ts" /> 

Use import...require

pass the --module commonjs flag to tsc then import what you require and export what you want to expose

In Parent.ts

 import Child = require('Child')   interface Parent {       children: Child[]  }   export = Parent 

In Child.ts

 import Parent = require('Parent')    interface Child {      parent: Parent  }   export = Child 

Please note, that you do not specify the extension '.ts' in require

like image 33
Bruno Grieder Avatar answered Sep 21 '22 15:09

Bruno Grieder