考虑一个简单的索引接口:
interface FormData {
[K: string]: string;
}
那个小家伙真棒。但是,在某些情况下,我想允许一个属性为字符串数组。
interface AcmeFormData extends FormData {
foobar: string[];
}
打字稿抱怨
类型为'string []'的属性'foobar'无法分配给字符串索引类型'string'。
仔细阅读文档,似乎以下内容应该可行,但也会抱怨。
interface FormData {
[K: string]: string;
foobar: string[];
}
应该注意,我希望避免使用联合类型([K: string]: string | string[];
),因为在99%的时间内,数据始终是单个字符串值,因此希望避免键入提示。
这可能吗?还是我想滥用打字稿?
答案 0 :(得分:3)
之所以不起作用,是因为[K: string]: string
表示接口中每个键的值必须是字符串,并且每个键都包含foobar
。我建议改做这样的事情:
interface FormData {
fields: { [field: string]: string }
somethingElse: string[]
}
答案 1 :(得分:3)
您可以通过使用交集而不是使用extends
来实现。 EG:
interface FormData {
[K: string]: string;
}
type AcmeFormData = FormData & { foobar: string[] };
declare const test: AcmeFormData;
test.foobar // string[]
test.anythingelse // string
但是,这确实会导致您需要注意一些问题,因为现在索引签名不再准确。因此,当打字稿使用该签名推断出某些内容时,您需要意识到这是错误的:
for (let key in test) {
// val is inferred to have type string, but be careful!
// In truth, val will be a string[] for the 'foobar' key,
// but typescript is no longer aware of that. So this will
// create a runtime error, but compiles without problems!
const val = test[key].toLowerCase();
}