【问题标题】:With T extending Record<string, any>, keyof T does not give 'string' as type使用 T 扩展 Record<string, any>,keyof T 不会将 'string' 作为类型
【发布时间】:2021-11-01 12:37:19
【问题描述】:

我正在努力实现以下目标:

type MyFormProps<FieldName extends keyof FormShape, FormShape extends Record<string, any>> = {
  id: string;
  value: FormShape[FieldName];
}

const formPropsBuilder = <FieldName extends keyof FormShape, FormShape extends Record<string, any>>(
  name: FieldName,
  form: FormShape,
): MyFormProps<FieldName, FormShape> => {
  return {
    id: name,
    value: form[name],
  }
}

但我收到一条错误消息,提示名称的类型为 string | number | symbol

这很奇怪,因为 FormShape 确实扩展了Record&lt;string, any&gt;,所以它的键必须是字符串。

正常吗? 如果是这样,有什么办法让它工作吗?

谢谢 ;)

游乐场链接: https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiBiB7ATgWwArMWAzgHngEsIAbAEwDkBDVaCAD2AgDsycoBrCERAMyiRoAygAsqkADQCUqUeLqMWbKACUIAYxRk8OYMkLMA5lKrMQAPnNQAvFADeAKChRCZAFxRd+owG4nUADcqEgBXCA9BWTFIAG0iUkoaCABdPwBfBwdNZl0oXhlMbBwAIRDCcghkGygCYnJqWigGJlZ2Lh5+SLlJaWFohRblNU1kbS8DYyhTC3MACn9mJIi6xNoJf3y0CJluiHWASg84SMLcWoSGvd6o+StrK0dnZAhgEORme39nVw9Fta-AsEwh5NqgYn8UutnBk0kA

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我认为有3种索引类型string | number | symbol 所以为了分配给它,您可能必须使 id 具有上述相同的类型。

    type MyFormProps = {
      id: string | number | symbol;
    }
    

    如果您认为输入始终是字符串,您也可以将类型转换为字符串:

    const formPropsBuilder = <K extends keyof T, T extends Record<string, any>>(name: K): MyFormProps => {
      return {
        id: name as string,    
      }
    }
    ``
    

    【讨论】:

      【解决方案2】:

      有额外的泛型类型的原因吗?我将其简化为:

      type MyFormProps = {
        id: string;
      }
      
      const formPropsBuilder = <FieldName extends keyof Record<string, any>>(name: FieldName): MyFormProps => {
        return {
          id: name,
        }
      }
      

      通过这种简化,错误消失了。

      【讨论】:

      • 如果FieldName extends keyof Record&lt;string, any&gt; 那么FieldName string(没有进一步的限制)。为什么要使用泛型?
      • 啊抱歉,这是一个好点:我的例子不完整。 FieldName extends FormShapeFormShape extends Record&lt;string, any&gt;,但可能是一个定义明确的字典。我把它简化了。
      • 我编辑了我的帖子以赋予示例更多意义。
      【解决方案3】:

      我也觉得这很奇怪。这是我的解决方法:

      type StringKey<T extends Record<string, any>> = keyof T extends string
        ? keyof T
        : never
      

      现在你有 StringKey&lt;Record&lt;string, any&gt;&gt; 扩展字符串。

      【讨论】:

        猜你喜欢
        • 2020-01-02
        • 1970-01-01
        • 2019-11-17
        • 2019-12-04
        • 1970-01-01
        • 1970-01-01
        • 2019-08-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多