如何在TypeScript中将导入的模块分配给带索引签名的字典类型?

时间:2017-09-03 23:34:53

标签: typescript module compiler-errors

my_dates.ts

export const birthday = new Date(1992, 12, 14);
export const anniversary = new Date(2014, 5, 9);
export const moonLanding = new Date(1969, 6, 20);

index.ts

import * as myDates from './my_dates';
type MyDateType = {[k: string]: Date};
let foo: MyDateType = myDates as MyDateType;

我收到以下错误:

Type 'typeof "<project>/my_dates"' cannot be converted to type 'MyDateType'.
  Index signature is missing in type 'typeof "<project>/my_dates"'.

它不能让我分配它的原因是什么?

  • 我尝试过使用和不使用类型转换。
  • 如果我改为使用type MyDateType = {[k: string]: any};,它可以正常运行,但我会丢失foo中的所有类型信息。
  • VSCode中的Intellisense能够自动完成myDates变量而不会出现任何问题。

2 个答案:

答案 0 :(得分:3)

嗯,我还没有看到人们试图像以前那样改变名称空间的类型。好吧,rest/spread object destructuring似乎有效:

import * as myDates from './my_dates';
type MyDateType = { [k: string]: Date };
let foo = { ...myDates } as MyDateType; // works
const a: Date = foo.anniversary; // okay
const b: Date = foo.birthday; // okay
const m: Date = foo.mothersDay; // STILL okay, but you asked for it 

我不确定你为什么要抛弃myDates中存在的确切密钥的知识,但这取决于你。注意:如果向Date添加一些非my_dates.ts属性,MyDateType断言将按预期失败。

希望有所帮助;祝你好运!

答案 1 :(得分:1)

导入的界面与{[k: string]: any}匹配,后者无法通过类型断言直接更改为{[k: string]: Date},这就是您收到错误的原因。

如果您确定在模块中只会出现类型为Date的导出,那么您可以使用:

let foo: MyDateType = myDates as any as MyDateType;

但更好的解决方案可能是构建my_dates模块,使其看起来像:

export const birthday = new Date(1992, 12, 14);
export const anniversary = new Date(2014, 5, 9);
export const moonLanding = new Date(1969, 6, 20);

const myDates = { birthday, anniversary, moonLanding };

export default myDates;

或类似的东西,取决于您的需求。

然后导入:

import myDates from './foo';

这已经有了一个可以断言的类型。