@
makelove 用 intersection type 虽然规避了同一个 interface 内声明的字段类型必须兼容 index signature 的 TS 报错,但其实这是一种错误用法,不报错可能就像你说的,.xxx 和 索引访问在进行类型交叉的时候互不干扰。
这个所谓的 index signature 必须兼容所有字段的设定,是为了规避在 bar['na'+'me'].getMonth() 这种场景下产生错误推断。
这两种类型交叉后,更准确地,我觉得
bar.name 应该推断为 string & Date ,但 JS 中怎么构造一个既是 string 又是 Date 的变量呢。
const bar2: Bar = { name: 'xx' as string & Date }
你看这样就不报错了,说明右边的 literal object 必须同时满足 Bar 的两个类型才能赋值。但是因为强行 as ,运行时 bar['na'+'me'].getMonth() 仍然要报错。
类型要安全那就只能加一层,把 name 摘出来:
interface Bar {
name: string;
dates: {[key: string]: Date}
}
或者像 #3 说的,name 用 symbol 。
module A {
const name = Symbol('name')
interface Bar {
[name]: string;
[key: string]: Date;
}
export const bar: Bar = {
[name]: 'test',
a: new Date,
bar: new Date
};
}