Circular Type References in 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
}
Solution 1:
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
Solution 2:
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
Solution 3:
I have about 10 ts files , in a Circular-Dependency-Hell .
The common methods can't help me any more , because the dependencies relation between 10 files is to complex.
At finally , I solved it. Using following 2 methods :
-
Install repo ———— "circular-dependency-plugin": "5.0.2"
This repo will helps me to find the place where circular occurs.
-
Using a designed internal.ts , to manage my import & export
I tried the method of this article :
How to fix nasty circular dependency issues once and for all in JavaScript & TypeScript
This amazing article tells me to create internal.ts .
and using like
export * form 'file-A' ; export * from 'file-B'
to manage my circular dependencies.It works very well when I use dependencies related to my 10 files, like this
import classA from '../internal.ts'
.
————————————————————————————————————
If the above method has no effect on you, I found another general solution:
Use
const File_Promise = import ('yourFilePath')"
to import other file or module .
when you need to use this one, use
File_Promise.then (file => { file.xxx(file.yyy) })
, just like using Promise syntax.
`
This will break the Circular-Dep Chain !
If i am you , I will continue this action until NO ERROR Reported by "circular-dependency-plugin".
————————————————————————————————————
Hope to help YOU !