TS4023:导出的变量<x>已从外部模块使用或正在使用名称<y>,但无法命名

时间:2017-05-10 18:21:33

标签: typescript types module declaration type-inference

之前我已经看过这个问题,但他们似乎没有涵盖这个特定的用例(或者他们没有工作/帮助)

import {Route} from 'vue-router';


export const detailRoute = {
  path: '/detail/:id',
  component: Detail,
  props: (route: Route) => ({
    state: route.query.state
  })
};

detailRoute使用Route,我正在导入,但我想作为一个名为import {Route}它不起作用?是否有不同的/更好的方法来做到这一点?我也尝试了export {Route};,但这没有用。

tsconfig.json:

    {
      "compilerOptions": {
        "target": "ES2017",
        "module": "ES2015",
        "moduleResolution": "Node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "forceConsistentCasingInFileNames": true,
        "allowSyntheticDefaultImports": true,
        "noEmitHelpers": true,
        "importHelpers": true,
        "pretty": true,
        "alwaysStrict": true,
        "declaration": true,
        "declarationDir": "./types",
        "lib": [
          "DOM",
          "ES2017",
          "DOM.Iterable",
          "ScriptHost"
        ],
        "baseUrl": "./client",
        "paths": {
          "styles/*": ["./app/core/styles/*"],
          "core/*": ["./app/core/*"],
          "components/*": ["./app/components/*"],
          "containers/*": ["./app/containers/*"],
          "assets/*": ["./assets/*"],
          "config/*": ["./config/*"]
        }
      }
    }

确切错误:

TS4023: Exported variable 'detailRoute' has or is using name 'Route' from external module "/Users/chris/<projectname>/node_modules/vue-router/types/router" but cannot be named.

3 个答案:

答案 0 :(得分:12)

编译器未能确定detailRoute的确切形状,因为它不知道Route的形状。

选项1

解决此问题的一种方法是从其源中导入Route,从而提供编译器确定detailRoute形状所需的信息。

import { Route } from "./../node_modules/vue-router/types/router";

export const detailRoute = {
  props: (route: Route) => null,
};

由于the index.d.ts file in vue-router(您在问题中导入的内容)重新导出Route,因此它不会向Route提供编译器的直接引用需要的。

选项2

另一个选择是完全选择detailRoute静态输入。

import { Route } from 'vue-router'; // index.d.ts

export const detailRoute: any = {
  props: (route: Route) => null,
};

由于any选择了静态类型,编译器不需要弄清楚detailRoute的形状。

选项3

另一个选项是您在自己的答案中所做的选项。由于您提供了类型注释,因此编译器不需要计算detailRoute的形状。

import { Route, RouteConfig } from 'vue-router'; // index.d.ts

export const detailRoute: RouteConfig = {
  props: (route: Route) => null,
};

另见

https://github.com/Microsoft/TypeScript/issues/5711

  

当尝试发出[模块]时,编译器需要编写一个表示模块形状的对象类型文字。但是范围中没有直接引用[Route]的名称,因此类型&#34;不能命名为&#34;并且出现了错误。

     

如果您添加[直接]导入[路线] ...错误应该消失。

答案 1 :(得分:7)

显然这是我问题的解决方案:

  import {Route, RouteConfig} from 'vue-router';


  export const detailRoute: RouteConfig = {
    path: '/detail/:id',
    component: Detail,
    props: (route: Route) => ({
      state: route.query.state
    })
  };

指定detailRoute是RouteConfig(后者又使用Route)解决了问题。我一定是误解了它应该如何工作,但这解决了它。

答案 2 :(得分:0)

我在键入rootReducer时遇到了这个问题,以防其他人也这样做。我正在导入由我也未导出的其他类型(状态,动作)组成的类型化的缩减器。

简短答案:从化简器导出所有动作状态类型!

当不导出其组成部分并且您依赖类型推断时,复合类型似乎无法很好地工作。在这种情况下,推断出rootReducer的类型(如果您只有多个化简器,那么将无法显式键入。)

const rootReducer = combineReducers({ typedReducerA, typedReducerB, ... }