【问题标题】:TypeScript: `'keyof R'` is not assignable to type 'string' because it can be either 'string | number | symbol'TypeScript:`'keyof R'` 不能分配给类型 'string',因为它可以是 'string |号码 |象征'
【发布时间】:2020-11-15 04:56:01
【问题描述】:

我有一个接受对象键的函数,有没有办法将键的类型缩小到只有string

function foo<R, K extends keyof R>(obj: R, key: K, array: string[]) {
  array.push(key); // Error????: Type 'string | number | symbol' is not assignable to type 'string'.
    
  // omit implementation details...
  return obj[key];
}

所以 TS 编译器说 'keyof R' 不能分配给类型 'string' 因为它可以是 'string |号码 |象征' 。我想知道是否有办法将其类型缩小到仅string,以便我们可以从中排除numbersymbol

我试过了,但语法上似乎错误

function foo<R, K extends Extract(keyof R, string)>(obj: R, key: K, array: string[]) {
  array.push(key);

  // omit implementation details...
  return obj[key];
}

【问题讨论】:

    标签: typescript


    【解决方案1】:

    你的通用语法错误,Extract(A, B) 必须是Extract&lt;A, B&gt;,所以函数foo&lt;R, K extends Extract&lt;keyof R, string&gt;&gt;(obj: R, key: K, array: string[])

    也就是说,当您关心 一个 对象时,确实没有理由让您的函数在 两个 上通用:

    
    function foo<R>(obj: R, key: Extract<keyof R, string>, array: string[]): void {
      array.push(key);
    }
    

    同样有效,而且更简单。

    如果要在键处返回对象的值,则需要第二种类型,最终得到:

    function foo<R, T extends Extract<keyof R, string>>(obj: R, key: T, array: string[]): R[T] {
      array.push(key);
      return obj[key];
    }
    foo({x: 3, y: 5}, 'x', array);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-10
      • 2022-07-27
      • 1970-01-01
      • 2019-11-17
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多