简体   繁体   English

TypeScript-如何检查对象是否在编译时实现接口?

[英]TypeScript - How to check if object implements interface at compile-time?

Question

Lets say I have two files - an interface file (like a header file in C) and an implementation file. 可以说我有两个文件-一个接口文件(如C中的头文件)和一个实现文件。

intf.ts (interface file): intf.ts (接口文件):

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

impl.ts (implementation file): impl.ts (实现文件):

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 ? 如何确定impl.ts的默认导出intf.ts实现了默认导出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. 我正在尝试学习干净的体系结构,并且TypeScript由于其静态类型检查而与干净的体系结构很好地兼容。 For example, dependency injection is easy to do in TypeScript. 例如,依赖注入很容易在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. 当模块依赖于其他模块,而不是依赖于名称和版本时(例如npm中的"package_name": "^1.0.2" ),该模块依赖于某个接口。 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! 感谢您的输入!

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: 您可以使用import('module')来获取import('module')类型,然后在此处形成可以在实现不正确的情况下出错的类型:

type Check<T extends import('./intf').default> = T;
type IsOk = Check<typeof import('./impl')['default']>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM