【发布时间】:2019-11-14 19:12:02
【问题描述】:
我有以下类型定义:
interface DefaultConfig {
state: {
initialState: AllState;
};
}
type UserConfig = {
[K in keyof DefaultConfig]: DefaultConfig[K];
};
// Could also use 'type UserConfig = Partial<DefaultConfig>;'
interface AssignDefaults {
(userConfig: UserConfig): DefaultConfig;
}
我在以下函数中使用这些:
const defaultConfig: DefaultConfig = {
state: {
initialState: defaultInitialState
}
};
const assignDefaults: AssignDefaults = userConfig => {
const thisUserConfig = userConfig;
Object.keys(userConfig).forEach(key => {
if (key in defaultConfig) {
const maybeObject = userConfig[key];
if (!!maybeObject && maybeObject.constructor === Object) {
thisUserConfig[key] = {
...(defaultConfig[key] || {}),
...userConfig[key]
};
}
}
});
return { ...defaultConfig, ...thisUserConfig };
};
我期望发生的是 userConfig[key] 应该等于 keyof DefaultConfig,因为这是在 UserConfig 索引签名中定义的。
但是,这不起作用,因为Object.keys(...) 将其返回值定义为string[]。这会导致 Typescript 错误:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'UserConfig'.
No index signature with a parameter of type 'string' was found on type 'UserConfig'.
Typescript 似乎无法确定 keyof DefaultConfig 也是一个字符串。
我知道我可以通过在DefaultConfig 接口中包含[key: string]: any 来消除此错误,但是我更不想这样做:
- 这些是它所代表的对象唯一允许的键和值(例如,
defaultConfig对象不应包含foo: "bar"作为键/值对,但是如果DefaultConfig包含索引签名,则允许这样做。 - 当我需要调用
defaultConfig.state.initialState时,我不希望它返回any的类型,如果包含该索引签名会发生这种情况。与如果我创建一个 constconst foo = assignDefaults(userConfigObject)然后调用foo.state.initialState相同。 - 除非绝对必要,否则我不喜欢在我的类型定义中使用
any。
这是 Typescript 的限制还是有一些解决方法?
【问题讨论】:
标签: typescript