Is it possible for typescript to allow only importing interfaces/types/enums from "folder", but not executable code like classes/functions etc?

Viewed 44

Question is as the title: Is it possible for typescript to allow only importing interfaces/types/enums from "folder", but not executable code like classes/functions etc?

Directory structure

  • A/source.ts
  • B/usage.ts

Contents of source.ts

export interface ExampleInterface {
  name: string
}
export type ExampleType = {special: boolean}
export enum ExampleEnum {
   x1: 1,
   x2: 2
}
export class SomeClass {}

Contents of usage.ts

// valid
import {ExampleInterface} from "../A/source"
// valid
import {ExampleType} from "../A/source"
// valid
import {ExampleEnum} from "../A/source"

// INVALID IMPORT
import {SomeClass} from "../A/source"

Why?

This allows avoiding duplicating certain interfaces in "monorepo" style project into separate folder. If you work with microservices, it could be serviceA and serviceB, service B wants to call api of serviceA and you would need to somehow clearly state what the api of serviceA is. That most likely will lead to duplication of interfaces. But it is important that serviceA does not import any code from serviceB.

Things to keep in mind

I am specifically interested in exactly this structure. There are workaround using different structure

Possible solutions that are rejected :)

a) using AST tree parsing and automatically copying interfaces. problem: expensive to develop & maintain

b) defining api in external tool and using that to generate necessary files. problem: "owner" of interface/type is moved to shared location. Would prefer to avoid that in this particular case

c) defining common parts in another "common" folder. problem: "owner" of interface/type is moved to shared location. Would prefer to avoid that in this particular case)

Special case is ENUM

Enums are values and need to be in JS files. But they also are 'constants' and lets assume --preserveConstEnums flag is set and there is no problems with enums being out of sync in differently compiled projects - in other words, all projects are compiled at the same time and released together in perfect sync.

So what is this about? Making coding faster by keeping ownership of interface/type/enum correct and they are located in their "best possible files" (directory A), but also make them sharable on other dependant directories (directory B).

Concrete details on the problem

It is a game that uses webworkers. Main thread is UI, while webworkers are "core" and "graphics". All three need to use same metadata, like "CarMeta" and "enum CarTypeId", but should not import any code from each other. Obvious solution is to have additional folder "meta" that is shared between all three "projects", but this moves "CarMeta" away from its "owner" - Car class for example that lives in "core project". In theory you could just avoid importing "executable code" and allow importing, but would be nice to have a tool that guarantees this.

Final words

I am aware this is awfully specific problem and question, but maybe someone has some awesome idea on how to make it better :)

0 Answers
Related