【问题标题】:typescript, import * as, no index signature with bracket property accessortypescript,import * as,没有带括号属性访问器的索引签名
【发布时间】:2018-06-16 12:50:48
【问题描述】:

我是打字稿的新手。我有一个从 javascript 转换的大型程序。我正在处理错误并添加类型,但我不知道如何解决这个问题。

myModule.ts

export const foo = { ... }
export const bar = { ... }

我的文件.ts

import * as myModule from './myModule'

function doesSomething(input: string) {
    return myModule[input]
}

Typescript 编译器错误:元素隐式具有“any”类型,因为类型“typeof "./myModule"' 没有索引签名。

我尝试过声明模块和命名空间或尝试实现接口,但似乎不起作用。我认为解决方案是在单独的文件中声明模块,但我似乎无法让 TS 识别它。这就是我认为可行的方法:

myModule.d.ts

interface MyModule {
    [key: string]: any
}

declare module 'myModule' {
    const myModule: MyModule
    export = myModule
}

也许添加一个指向 myFile 的三斜杠:

我的文件.ts

/// <reference path="./myModule.d.ts" />
import * as myModule from './myModule'

function doesSomething(input: string) {
    return myModule[input]
}

但这并没有真正改变任何事情。

【问题讨论】:

  • 导出您的界面并重试
  • @Hey24sheep 似乎没有任何改变

标签: typescript


【解决方案1】:

如果您只希望使用与myModule 的名称相同的字符串调用doesSomething,您可以执行类似的操作

import * as myModule from './myModule';

type ModuleType = typeof myModule;

function doesSomething<K extends keyof ModuleType>(input: K): ModuleType[K] {
    return myModule[input]
}

您将获得一个反映foobar等类型的更准确的返回类型。

【讨论】:

  • 这回答了问题并摆脱了错误消息,因此被接受。但是,我实际上需要访问 foo/bar 上的属性,现在我有新的错误要解决,即“类型 'typeof”./myModule“[K]' 上不存在属性 'myProperty'。此外,任何文件导入 myModule 将需要与 myModule 一起提供的最佳类型定义。
  • 是的,任何想要这个的人都需要一些描述模块形状的导出类型。您可以编写一个模块满足的接口,并使用它来代替ModuleType。不过,我不确定为什么您在调用 doesSomething("foo") 后会遇到其他访问属性的问题。
  • 关于访问“myProperty”的错误是因为并非 myModule 上的所有导出实际上都具有“myProperty” --- 所以,该错误是所需的行为,并重申我决定转向打字稿第一名。我认为接口是长期的正确方法,但公认的答案是一个很好的临时解决方案,可以帮助解决编译器错误。谢谢。
  • 还有这个奇怪的 hack:function doesSomething&lt;K extends keyof ModuleType&gt;(input: K | string) { return input in myModule ? myModule[input as K] : undefined; }
猜你喜欢
  • 2019-04-06
  • 2016-12-08
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 2014-11-28
  • 2017-07-16
  • 2020-02-02
  • 2014-10-06
相关资源
最近更新 更多