2

Question

Lets say I have two files - an interface file (like a header file in C) and an implementation file.

intf.ts (interface file):

export default interface
{
  foo(baz: number): boolean
  bar(baz: number): string
};

impl.ts (implementation file):

export default
{
  foo(baz: number): boolean
  {
    return baz > 0;
  }

  bar(baz: number): string
  {
    return baz > 0 ? "john" : "doe"
  }
};

How would I determine if the default export of impl.ts implements the default export intf.ts? Assume that I cannot modify either of these files.

Something like:

import intf from `./intf.ts`;
import impl from `./impl.ts`;

if (impl implements intf)
  console.log("Good input!");
else
  console.log("Bad input! Input does not implement interface!");

Note: The answer does not have to be determined inside a typescript script.


My partly working solution

Here is a solution I came up with that partly works:

check_if_implements.ts

import intf from `./intf.ts`;
import impl from `./impl.ts`;

function check(_: intf) {};
check(impl);

This script will create a compile-time error if the implementation does not implement the interface.

I can then compile this script and check if there is an error to determine the answer.

There is one problem with this: How do I distinguish (in code) a 'does not implement' error from any other error?


Why am I doing this?

I am trying to learn clean architecture and TypeScript works well with clean architecture because of its static type checking. For example, dependency injection is easy to do in TypeScript.

My plan is that each "module" (entity, use case, interface implementation, etc.) has an "interface" and "implementation" file (like in the question).

When modules depend on other modules, rather than depending on a name and version (like "package_name": "^1.0.2" in npm), the module depends on a certain interface. The module can copy an interface from an existing module or create their own.

The idea is that any implementation can be plugged into modules that require implementations for interfaces. I like to call this "static dependency injection", and of course "run-time dependency injection" should still be used wherever makes sense.

So this now requires me to determine if a statically injected implementation implements an interface.


Thanks for any input!

2
  • I think you'd want to use the Compiler API offered by TypeScript to write a program that checks if the implementation satisfies the interface. Commented May 7, 2019 at 16:07
  • @IngoBürk Ah, interesting, I didn't know that existed. I'll take a look at it. Thanks Commented May 7, 2019 at 16:27

1 Answer 1

3

You can check this fully in the type system. You can use import('module') to get teh type of a module and form there you can build a type that will error if the implementation is incorrect:

type Check<T extends import('./intf').default> = T;
type IsOk = Check<typeof import('./impl')['default']>
Sign up to request clarification or add additional context in comments.

4 Comments

But this will have the same problem of resulting in a compile time error that would somehow have to be parsed, no?
@IngoBürk That is true.. I might not have gotten the whole point of what op is trying to do .. its an build time solution.. not sure how you can detect the error, maybe add a marker in the type type Check<T extends import('./intf').default | "Implements interf.ts"> = T; so the error will be Type '{ foo(baz: number): boolean; barr(baz: number): string; }' does not satisfy the constraint 'I | "Implements interf.ts"'. making it easier to look for ..
That looks like it might be the best solution, but I will wait and see if there are any other solutions. Thanks for the help
@DavidCallanan sure, no rush, others might have better ideas. If you need any help with the solution let me knwo :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.