打字稿导入别名+桶文件 [英] Typescript import alias + barrel file

查看:83
本文介绍了打字稿导入别名+桶文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我由于在angular/ngrx/typescript生态系统中某种事物的特定行为(我无法确定可能的根本原因)而花费了很多时间.

I spent a lot of time recently because of a particular behavior of something (and I could not identify the possible root cause) in angular/ngrx/typescript ecosystem.

场景:我已经建立了一些效果,并将它们导出到桶文件(index.ts)中:

The scenario: I've built up some effects and I have exported them in a barrel file (index.ts):

import {MyEffects} from './my.effects';

export const effects: any[] = [
  MyEffects,
];

然后,在另一个桶文件中,在我的目录结构中上一层,我具有:

Then, in another barrel file, one level up in my directory structure, I have:

import * as EFFECTS from './effects'
export {EFFECTS};

-store
 |-index.ts   <= export {EFFECTS}
 |-effects
   |-index.ts
   |-my.effects.ts

最后,在NgModule的imports数组中:

And, finally, in the NgModule's imports array:

  [
   ...
   EffectsModule.forFeature(EFFECTS.effects),
   ...
  ]

当我尝试对此进行编译时,我得到了一条很短的错误消息:

When I tried to compile this, I got a way too short error message:

ERROR in params.map is not a function

仅此而已.而且它阻止了我的项目的编译.还有更多...如果我运行ng serve,也会发生该错误,但是,如果在ng serve监视文件更改时进行了任何更改,它只会成功地重新编译项目.

And nothing more. And it prevented my project from compiling. And more... if I run ng serve the error also occurred, but if I changed anything while ng serve was watching for files changes, it simply recompiled the project successfully.

整天寻找可能导致它的原因之后,我发现别名部分没有按照我认为应该做的去做.然后,我对结构进行了一些更改,现在可以按预期运行

After an entire day looking for what could possibly be causing it, I figured out that the alias part wasn't doing what I thought it should do. Then, I've changed a little bit the structure and it's now working as expected

在第一个桶文件中:

import {MyEffects} from './my.effects';

export const EFFECTS: any[] = [
  MyEffects,
];

在上层的桶文件中:

export * from './effects'

// instead of:
// import * as SOMETHING from './effects'
// export {SOMETHING};

NgModel中:

  [
   ...
   EffectsModule.forFeature(EFFECTS),
   ...
  ]

但是...为什么?

我误解了此过程的任何部分吗?

But... why???

Am I misunderstanding any part of this process?

我不确定这是否重要,但是注册效果的功能是延迟加载的.

I'm not sure if this is important, but the feature that is registering the effects is lazy loaded.

推荐答案

您正在创建一个奇怪的层次结构. export *import/export的行为方式不同.

You are creating a weird hierarchy. export * and import/export don't behave in the same way.

使用export *时,TypeScript的行为就像该文件中所有导出的符号实际上都在文件内部一样,即使它们是从其他位置导入的也是如此.换句话说,该模块只是层次结构中的一个透明级别,仅对缩短路径有用(您将可以用import {foo} from './module'代替import {foo} from './module/src/foo).

When you use export *, TypeScript behaves like all the exported symbols in that file are actually inside the file, even if they were imported from elsewhere. In other words, that module is just a transparent level in the hierarchy and it's only useful for shortening the paths (you will be able to write import {foo} from './module' in place of import {foo} from './module/src/foo).

相反,当您使用类似的内容时:

Instead, when you use something like:

import * as smth from './path';
export {smth}

您将介绍一个前所未有的更高级别.它是smth关键字.您不会遗忘smth键,它在那里,并且正在包装您的整个模块.

You are introducing a further level that wasn't there before. And it is the smth keyword. You won't get rid of the smth key, it's there and it's now wrapping your whole module.

回到您的示例,您应该编辑问题,以显示如何在NgModule中导入Effects. 如果您以如下方式导入它:

Going back to your example, you should edit your question showing how you import Effects in your NgModule. If you imported it like:

import * as effects from './effects.ts';

然后,您将再次引入一个包装所有变量的新符号,因此正确的路径将是effects.effects.effects.etc.

Then you're introducing again a new symbol that wraps all the variables, so the correct path will be effects.effects.effects.etc.

使用解构和export *可以使您导入和导出变量,而无需创建包装器.

Using destructuring and export *, instead, will let you import and export variables without creating wrappers.

现在的问题是,为什么编译器没有警告您?因为打字稿编译器通常善于捕获这些类型的问题.解决方案可能在这里:

The question now is, why didn't the compiler warn you? Because the typescript compiler is usually good at catching these types of problems. The solution is likely here:

export const effects: any[] = [

删除类型定义(any[])并让TypeScript干扰类型,我很确定它会向您显示您丢失的错误.

Remove the type definition (any[]) and let TypeScript interfere the type, I'm pretty sure it will show you the error that you were missing.

这篇关于打字稿导入别名+桶文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆