【问题标题】:Typescript issue with Object.keys index signatureObject.keys 索引签名的打字稿问题
【发布时间】: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 来消除此错误,但是我更不想这样做:

  1. 这些是它所代表的对象唯一允许的键和值(例如,defaultConfig 对象不应包含foo: "bar" 作为键/值对,但是如果DefaultConfig 包含索引签名,则允许这样做。
  2. 当我需要调用defaultConfig.state.initialState 时,我不希望它返回any 的类型,如果包含该索引签名会发生这种情况。与如果我创建一个 const const foo = assignDefaults(userConfigObject) 然后调用 foo.state.initialState 相同。
  3. 除非绝对必要,否则我不喜欢在我的类型定义中使用 any

这是 Typescript 的限制还是有一些解决方法?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我想通了……

    - Object.keys(userConfig).forEach(key => {
    + (Object.keys(userConfig) as (keyof DefaultConfig)[]).forEach(key => {
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 2018-12-15
      • 2021-05-20
      相关资源
      最近更新 更多